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.