Why is D slower than LuaJIT?
Andrej Mitrovic
andrej.mitrovich at gmail.com
Wed Dec 22 20:56:31 PST 2010
That's odd, I'm getting opposite results:
iota = 78ms
baseline = 187ms
Andreas' old code gives:
421ms
This is over multiple runs so I'm getting the average out of about 20 runs.
On 12/23/10, Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> On 12/22/10 4:04 PM, Andreas Mayer wrote:
>> To see what performance advantage D would give me over using a scripting
>> language, I made a small benchmark. It consists of this code:
>>
>>> auto L = iota(0.0, 10000000.0);
>>> auto L2 = map!"a / 2"(L);
>>> auto L3 = map!"a + 2"(L2);
>>> auto V = reduce!"a + b"(L3);
>>
>> It runs in 281 ms on my computer.
>>
>> The same code in Lua (using LuaJIT) runs in 23 ms.
>>
>> That's about 10 times faster. I would have expected D to be faster. Did I
>> do something wrong?
>>
>> The first Lua version uses a simplified design. I thought maybe that is
>> unfair to ranges, which are more complicated. You could argue ranges have
>> more features and do more work. To make it fair, I made a second Lua
>> version of the above benchmark that emulates ranges. It is still 29 ms
>> fast.
>>
>> The full D version is here: http://pastebin.com/R5AGHyPx
>> The Lua version: http://pastebin.com/Sa7rp6uz
>> Lua version that emulates ranges: http://pastebin.com/eAKMSWyr
>>
>> Could someone help me solving this mystery?
>>
>> Or is D, unlike I thought, not suitable for high performance computing?
>> What should I do?
>
> I reproduced the problem with a test program as shown below. On my
> machine the D iota runs in 108ms, whereas a baseline using a handwritten
> loop runs in 43 ms.
>
> I then replaced iota's implementation with a simpler one that's a
> forward range. Then the performance became exactly the same as for the
> simple loop.
>
> Andreas, any chance you could run this on your machine and compare it
> with Lua? (I don't have Lua installed.) Thanks!
>
>
> Andrei
>
> // D version, with std.algorithm
> // ~ 281 ms, using dmd 2.051 (dmd -O -release -inline)
>
> import std.algorithm;
> import std.stdio;
> import std.range;
> import std.traits;
>
> struct Iota2(N, S) if (isFloatingPoint!N && isNumeric!S) {
> private N start, end, current;
> private S step;
> this(N start, N end, S step)
> {
> this.start = start;
> this.end = end;
> this.step = step;
> current = start;
> }
> /// Range primitives
> @property bool empty() const { return current >= end; }
> /// Ditto
> @property N front() { return current; }
> /// Ditto
> alias front moveFront;
> /// Ditto
> void popFront()
> {
> assert(!empty);
> current += step;
> }
> @property Iota2 save() { return this; }
> }
>
> auto iota2(B, E, S)(B begin, E end, S step)
> if (is(typeof((E.init - B.init) + 1 * S.init)))
> {
> return Iota2!(CommonType!(Unqual!B, Unqual!E), S)(begin, end, step);
> }
>
> void main(string args[]) {
> double result;
> auto limit = 10_000_000.0;
> if (args.length > 1) {
> writeln("iota");
> auto L = iota2(0.0, limit, 1.0);
> result = reduce!"a + b"(L);
> } else {
> writeln("baseline");
> result = 0.0;
> for (double i = 0; i != limit; ++i) {
> result += i;
> }
> }
> writefln("%f", result);
> }
>
More information about the Digitalmars-d
mailing list