On Friday, 19 December 2014 at 10:41:04 UTC, bearophile wrote:
A case where the usage of ranges (UFCS chains) leads to very bad performance:


import std.stdio: writeln;
import std.algorithm: map, join;

uint count1, count2;

const(int)[] foo1(in int[] data, in int i, in int max) {
    count1++;

    if (i < max) {
        typeof(return) result;
        foreach (immutable n; data)
            result ~= foo1(data, i + 1, max);
        return result;
    } else {
        return data;
    }
}

const(int)[] foo2(in int[] data, in int i, in int max) {
    count2++;

    if (i < max) {
        return data.map!(n => foo2(data, i + 1, max)).join;
    } else {
        return data;
    }
}

void main() {
    const r1 = foo1([1, 2, 3, 4, 5], 1, 7);
    writeln(count1); // 19531
    const r2 = foo2([1, 2, 3, 4, 5], 1, 7);
    writeln(count2); // 1111111
    assert(r1 == r2); // Results are equally correct.
}


Can you tell why? :-)

Bye,
bearophile

Changed to
return data.map!(n => foo2(data, i + 1, max)).cache.joiner.array; then it produced the same result as array version. `map.cache.join` resulted in 597871.

Reply via email to