[Issue 9581] Exceptions are too slow

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Mon Jan 12 10:08:47 PST 2015


https://issues.dlang.org/show_bug.cgi?id=9581

--- Comment #29 from bearophile_hugs at eml.cc ---
(In reply to Adam D. Ruppe from comment #27)
> Is this still a problem? (Came across this on a search) In the last couple
> years, we've done some changes to the stack trace generation on Windows and
> Linux which yielded gigantic speedups.

On Windows 32 bit I see Java exceptions about twice faster than D ones
(compiled with dmd). This means that for many practical purposes D exceptions
are fast enough.

Benchmark done with the following code, with n = 500000.

ldc2 for Windows is about 4 or 5 times slower than DMD in this benchmark.

------------------------

final class Lo_Exception extends Exception {
    int num = 0;
    public Lo_Exception(int num) {
        this.num = num;
    }
}

final class Hi_Exception extends Exception {
    int num = 0;
    public Hi_Exception(int num) {
        this.num = num;
    }
}

public final class except {
    static int Lo = 0, Hi = 0;

    public static void some_function(int n) {
        try {
            hi_function(n);
        } catch (Exception e) {
            System.out.println("We shouldn't get here: " + e);
        }
    }

    public static void hi_function(int n) throws Hi_Exception, Lo_Exception {
        try {
            lo_function(n);
        } catch (Hi_Exception e) {
            Hi++;
        }
    }

    public static void lo_function(int n) throws Hi_Exception, Lo_Exception {
        try {
            blowup(n);
        } catch (Lo_Exception e) {
            Lo++;
        }
    }

    public static void blowup(int n) throws Hi_Exception, Lo_Exception {
        if ((n % 2) == 0)
            throw new Lo_Exception(n);
        else
            throw new Hi_Exception(n);
    }

    public static void main(String args[]) {
        final int n = Integer.parseInt(args[0]);

        for (int i = 0; i < n; i++)
            some_function(i);
        System.out.println("Exceptions: HI=" + Hi + " / LO=" + Lo);
    }
}

--------------------

import std.conv: to;

enum bool SLOW = true; // You can change this.

static if (SLOW) {
    import std.stdio: printf = writef;
} else {
    import core.stdc.stdio: printf;
}

__gshared uint HI, LO;

final class HiException : Exception {
    uint n;
    this(in uint n) pure nothrow {
        this.n = n;
        super(null);
    }
}

final class LoException : Exception {
    uint n;
    this(in uint n) pure nothrow {
        this.n = n;
        super(null);
    }
}

void blowup(in uint n) {
    if (n % 2)
        throw new LoException(n);
    else
        throw new HiException(n);
}

void loFunction(in uint n) {
    try {
        blowup(n);
    } catch (LoException ex) {
        LO++;
    }
}

void hiFunction(in uint n) {
    try {
        loFunction(n);
    } catch(HiException ex) {
        HI++;
    }
}

void someFunction(in uint n) {
    try {
        hiFunction(n);
    } catch {
        printf("We shouldn't get here\n");
    }
}

void main(in string[] args) {
    uint n = args.length > 1 ? args[1].to!uint : 1;

    while (n--)
        n.someFunction;
    printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
}

--------------------

--


More information about the Digitalmars-d-bugs mailing list