D outperformed by C++, what am I doing wrong?

amfvcg via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 13 00:51:32 PDT 2017


On Sunday, 13 August 2017 at 07:30:32 UTC, Daniel Kozak wrote:
> Here is more D idiomatic way:
>
> import std.stdio : writeln;
> import std.algorithm.comparison: min;
> import std.algorithm.iteration: sum;
> import core.time: MonoTime, Duration;
>
>
> auto sum_subranges(T)(T input, uint range)
> {
>     import std.array : array;
>     import std.range : chunks, ElementType;
>     import std.algorithm : map;
>
>     if (range == 0)
>     {
>         return ElementType!(T)[].init;
>     }
>     return input.chunks(range).map!(sum).array;
> }
>
> unittest
> {
>     assert(sum_subranges([1,1,1], 2) == [2, 1]);
>     assert(sum_subranges([1,1,1,2,3,3], 2) == [2, 3, 6]);
>     assert(sum_subranges([], 2) == []);
>     assert(sum_subranges([1], 2) == [1]);
>     assert(sum_subranges([1], 0) == []);
> }
>
>
> int main()
> {
>     import std.range : iota, array;
>     auto v = iota(0,1000000);
>     int sum;
>     MonoTime beg = MonoTime.currTime;
>     for (int i=0; i < 100; i++)
>         sum += cast(int)sum_subranges(v,2).length;
>     MonoTime end = MonoTime.currTime;
>     writeln(end-beg);
>     writeln(sum);
>     return sum;
> }
>
> On Sun, Aug 13, 2017 at 9:13 AM, Daniel Kozak 
> <kozzi11 at gmail.com> wrote:
>
>> this works ok for me with ldc compiler, gdc does not work on 
>> my arch machine so I can not do comparsion to your c++ versin 
>> (clang does not work with your c++ code)
>>
>> import std.stdio : writeln;
>> import std.algorithm.comparison: min;
>> import std.algorithm.iteration: sum;
>> import core.time: MonoTime, Duration;
>>
>>
>> T[] sum_subranges(T)(T[] input, uint range)
>> {
>>     import std.array : appender;
>>     auto app = appender!(T[])();
>>     if (range == 0)
>>     {
>>         return app.data;
>>     }
>>     for (uint i; i < input.length; i=min(i+range, 
>> input.length))
>>     {
>>         app.put(sum(input[i..min(i+range, input.length)]));
>>     }
>>     return app.data;
>> }
>>
>> unittest
>> {
>>     assert(sum_subranges([1,1,1], 2) == [2, 1]);
>>     assert(sum_subranges([1,1,1,2,3,3], 2) == [2, 3, 6]);
>>     assert(sum_subranges([], 2) == []);
>>     assert(sum_subranges([1], 2) == [1]);
>>     assert(sum_subranges([1], 0) == []);
>> }
>>
>>
>> int main()
>> {
>>     import std.range : iota, array;
>>     auto v = iota(0,1000000).array;
>>     int sum;
>>     MonoTime beg = MonoTime.currTime;
>>     for (int i=0; i < 100; i++)
>>         sum += cast(int)sum_subranges(v,2).length;
>>     MonoTime end = MonoTime.currTime;
>>     writeln(end-beg);
>>     writeln(sum);
>>     return sum;
>> }
>>
>> On Sun, Aug 13, 2017 at 9:03 AM, Neia Neutuladh via 
>> Digitalmars-d-learn < digitalmars-d-learn at puremagic.com> wrote:
>>
>>> [...]

Thank you all for the replies. Good to know the community is 
alive in d :)

Let's settle the playground:
D  : http://ideone.com/h4fnsD
C++: http://ideone.com/X1pyXG

Both using GCC under the hood.
C++ in 112 ms;
D in :
- 2.5 sec with original source;
- 2.5 sec with Daniel's 1st version;
- 5 sec timeout exceeded with Daniel's 2nd version;
- 1.8 sec with Neia-like preallocation;

So still it's not that neaty.

(What's interesting C++ code generates 2KLOC of assembly, and 
Dlang @ ldc 12KLOC - checked at godbolt).

P.S. For C++ version to work under clang, the function which 
takes (BinaryOp) must go before the other one (my bad).


More information about the Digitalmars-d-learn mailing list