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