Two CTFE benchmarks

bearophile bearophileHUGS at lycos.com
Sun Mar 28 08:13:18 PDT 2010


It's a lot of time I don't show benchmarks here :-)
I have taken the timings of run time or compile time of a integer-based function (nqueens) and a function that works with small arrays of integers (adapted from the Shootout).

I have used dmd 2.042 with -O -release -inline
The timings for the CFTE version don't include the printing on screen, I have just timed the compile time.
The CPU is a Celeron at about 2.3 GHz. Code is shown below.


Timings nqueens, seconds:
  N=         10    11     12    13    14    15
  ctfe:    0.43  1.83  23.40     -     -     -
  runtime: 0.04  0.04   0.05  0.13  0.55  3.21


Timings fannkuch, seconds:
  N=          6     7      8     9    10    11
  ctfe:    0.22  0.51  17.50     -     -     -
  runtime: 0.03  0.03   0.04  0.07  0.43  4.63


I have not timed ldc, but usually it's about 20-30% faster than dmd at CFTE (and often 100-300% faster than dmd at runtime).

The CFTE is quite slower, but the main problem is that it uses a too much large amount of RAM. Reducing the RAM used can probably speed up too a little.

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

// nqueens

import std.c.stdio: printf;

// the original code is not mine
uint nqueens(uint c, uint ll=0, uint r=0, uint n=0) {
    uint b;
    if (~c)
        for (uint
             S = ll | c | r; ~0U != S;
             b = ~S & (S + 1), S |= b, n = nqueens(c | b, (ll | b) << 1, (r | b) >> 1, n)
            ) {}
    else
        n++;
    return n;
}

enum int n = 10;
version(ctfe) enum uint result = nqueens(~0U >> n); // ctfe
void main() {
    version(ctfe) {} else uint result = nqueens(~0U >> n); // runtime
    printf("nqueens(%d) = %u\n", n, result);
}

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

// fannkuch

import std.c.stdio: printf;

int fannkuch(int n) {
    int i, j, k, t, flips, maxFlipsCount, check;
    int r = n;
    auto perm = new int[n];
    auto perm1 = new int[n];
    auto count = new int[n];

    foreach (ist; 0 .. n)
        perm1[ist] = ist;
    for ( ; ; ) {
        if (check < 30) {
            //pragma(msg, permToString(perm1)); // not possible
            check++;
        }

        while (r != 1) {
            count[r - 1] = r;
            r--;
        }

        if (!(perm1[0] == 0 || perm1[n-1] == n-1)) {
            foreach (ist; 0 .. n)
                perm[ist] = perm1[ist];

            flips = 0;
            i = perm[0];
            do {
                for (j = 1, k = i - 1; j < k; j++, k--) {
                    t = perm[j];
                    perm[j] = perm[k];
                    perm[k] = t;
                }
                flips++;
                t = perm[i];
                perm[i] = i;
                i = t;
            } while(i);

            if (flips > maxFlipsCount)
                maxFlipsCount = flips;
        }

        for ( ; ; ) {
            if (r == n)
                return maxFlipsCount;
            t = perm1[0];
            for (i = 0; i < r; ) {
                j = i + 1;
                perm1[i] = perm1[j];
                i = j;
            }
            perm1[r] = t;

            count[r]--;
            if (count[r] > 0)
                break;
            r++;
        }
    }
}


/*
This is faster as run-time function:

int fannkuch(int n)() {
    int i, j, k, t, flips, maxFlipsCount, check;
    int r = n;
    int[n] perm, perm1, count;

    foreach (ist; Range!(0, n))
        perm1[ist] = ist;
    for ( ; ; ) {
        if (check < 30) {
            //pragma(msg, permToString(perm1)); // not possible because of many D bugs
            check++;
        }

        while (r != 1) {
            count[r - 1] = r;
            r--;
        }

        if (!(perm1[0] == 0 || perm1[n-1] == n-1)) {
            foreach (ist; Range!(0, n))
                perm[ist] = perm1[ist];
...
*/


enum int n = 11;
version(ctfe) enum int result = fannkuch(n); // ctfe
void main() {
    version(ctfe) {} else int result = fannkuch(n); // runtime
    printf("Pfannkuchen(%d) = %d\n", n, result);
}

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

Bye,
bearophile



More information about the Digitalmars-d mailing list