Performance penalty for using ranges
bearophile
bearophileHUGS at lycos.com
Sun Aug 25 07:54:03 PDT 2013
Paul Jurczak:
> I wrote a few versions of a palindrome testing function and
> noticed that versions using ranges
> (isPalindrome1..isPalindrome3) are 3 times slower than array
> indexing one (isPalindrome0). Is there a more efficient way of
> using ranges?
I have modified and improved and fixed your code a little:
import std.stdio, std.datetime, std.array, std.typetuple,
std.range, std.algorithm;
bool isPalindrome0(T)(in T[] s) pure nothrow {
size_t i = 0;
for (; i < s.length / 2 && s[i] == s[$ - i - 1]; ++i) {}
return i == s.length / 2;
}
bool isPalindrome1(T)(T[] s) pure nothrow {
while (s.length > 1 && s.front == s.back) {
s.popBack;
s.popFront;
}
return s.length <= 1;
}
bool isPalindrome2(T)(T[] s) pure nothrow {
for (;
s.length > 1 && s.front == s.back;
s.popBack, s.popFront) {}
return s.length <= 1;
}
bool isPalindrome3(T)(in T[] s) pure nothrow {
foreach (immutable i; 0 .. s.length / 2)
if (s[i] != s[$ - i - 1])
return false;
return true;
}
/// A high-level version.
bool isPalindrome4(T)(in T[] s) /*pure nothrow*/ {
return s.retro.equal(s);
}
int test(alias F)(in int nLoops) /*pure nothrow*/ {
int[10] a;
typeof(return) n = 0;
foreach (immutable _; 0 .. nLoops) {
a[4] = !a[4];
n += F(a);
}
return n;
}
void main() {
enum size_t nLoops = 60_000_000;
StopWatch sw;
foreach (alg; TypeTuple!(isPalindrome0, isPalindrome1,
isPalindrome2, isPalindrome3,
isPalindrome4)) {
sw.reset;
sw.start;
immutable n = test!alg(nLoops);
sw.stop;
writeln(n, " ", sw.peek.msecs);
}
}
Using a compiler with a better optimizing back-end (especially
with a better inlining), the timings show that the faster
versions are the second and third, but all of them have a very
similar performance (the last one reads the whole array twice, so
it's a little slower, as expected):
...>ldmd2 -O -release -inline -noboundscheck -run test2.d
30000000 1150
30000000 1073
30000000 1038
30000000 1215
30000000 1621
Someday a function like isPalindrome4 will be pure & nothrow.
Bye,
bearophile
More information about the Digitalmars-d
mailing list