Jump to page: 1 2 3
Thread overview
Woeful performance of D compared to C++
Jan 18, 2007
rael
Jan 18, 2007
Kirk McDonald
Jan 18, 2007
Bill Lear
Jan 18, 2007
Kirk McDonald
Jan 18, 2007
rael
Jan 18, 2007
Pragma
Jan 18, 2007
Bill Lear
Jan 18, 2007
Dave
Jan 18, 2007
Sean Kelly
Jan 19, 2007
Walter Bright
Jan 18, 2007
Dave
Jan 18, 2007
Walter Bright
Jan 18, 2007
Lionello Lunesu
Jan 19, 2007
Walter Bright
Jan 19, 2007
Bill Baxter
Jan 19, 2007
janderson
Jan 19, 2007
Jeff McGlynn
Jan 19, 2007
Paulo Herrera
Jan 19, 2007
Dave
Jan 19, 2007
Paulo Herrera
Jan 19, 2007
janderson
Jan 18, 2007
Bill Lear
Jan 18, 2007
Sean Kelly
January 18, 2007
In other benchmarks I've seen, D seems quite competitive with C/C++.

I seem to have written a very simple program that shows D in a very poor light compared to C++.  I wonder if it is my inexperience.

I am using dmd 1.0, and g++ 4.1.1 under Linux Fedora Core 6, running on a 3.0 GHz Pentium 4 with 1 gig of RAM.

The program is a simulation of the Monty Hall problem (see Wikipedia).

Here is the D program:

import std.random;
import std.stdio;

void main() {
    const uint n = 10_000_000;
    ubyte doors;
    uint wins, wins_switching;

    for (uint i; i < n; ++i) {
        doors |= cast(ubyte)(1 << rand() % 3);

        if (doors & 1) {
            ++wins;
        } else {
            ++wins_switching;
        }

        doors = 0;
    }

    writefln("Wins switching: %d [%f%%]", wins_switching,
             (wins_switching / cast(double) n) * 100);
    writefln("Wins without switching: %d [%f%%]", wins,
             (wins / cast(double) n) * 100);
}

Compiled with:

% dmd -I/opt/dmd/src/phobos -O -inline monty.d -ofmonty_d gcc monty.o -o monty_d -m32 -lphobos -lpthread -lm

and here is the C++:

#include <iostream>
#include <cstdlib>

int main() {
    unsigned char doors = 0;
    const unsigned int n = 10000000;
    unsigned int wins = 0, wins_switching = 0;

    for (unsigned int i = 0; i < n; ++i) {
        unsigned char r = 1 << (rand() % 3);
        doors |= r; // place the car behind a random door

        if (doors & 1) { // choose zero'th door, same as random choice
            ++wins;
        } else {
            ++wins_switching;
        }

        doors ^= r; // zero the door with car
    }

    const double d = n / 100;
    std::cout << "Win % switching: " << (wins_switching / d)
              << "\nWin % no switching: " << (wins / d) << '\n';
}

Compiled with:

% g++ -O3 -o monty_cc

Execution times (best of 5):

% time monty_d
Wins switching: 6665726 [66.657260%]
Wins without switching: 3334274 [33.342740%]

real    0m2.444s
user    0m2.442s
sys     0m0.002s

% time monty_cc
Win % switching: 66.6766
Win % no switching: 33.3234

real    0m0.433s
user    0m0.432s
sys     0m0.001s


Any help would be appreciated.

Thanks.


Bill
--
Bill Lear
r * e * @ * o * y * a * c * m
* a * l * z * p * r * . * o *

January 18, 2007
rael@seesig.com wrote:
> Compiled with:
> 
> % dmd -I/opt/dmd/src/phobos -O -inline monty.d -ofmonty_d

Perhaps the -release flag would make a difference?

Also, that -I option should be redundant if you've set up your dmd.conf file properly.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
January 18, 2007
rael@seesig.com wrote:
> In other benchmarks I've seen, D seems quite competitive with C/C++.
> 
> I seem to have written a very simple program that shows D in a very
> poor light compared to C++.  I wonder if it is my inexperience.
[snip]
> Any help would be appreciated.

I'm gobsmacked.  No array concatenation, strings, large allocations, or even floating point.  Just integer math and comparisons.

Check the obvious stuff first: disable the GC, compile with "-inline -release" for GDC to match the "-O3 -o" that you're using on GCC.

The only part of that loop that is of any consequence is the call to rand() - odds are they are two completely different algorithms, with D's being slower (performance test anyone?).  Everything else should reduce to almost the same exact machine code.

-- 
- EricAnderton at yahoo
January 18, 2007
D's rand() is slow.

//import std.random;
extern (C) int rand();
import std.stdio;
import std.conv;

void main()
{
    const uint n = 10_000_000;
    ubyte doors;
    uint wins, wins_switching;

    for (uint i; i < n; ++i) {
        doors |= cast(ubyte)(1 << rand() % 3);

        if (doors & 1) {
            ++wins;
        } else {
            ++wins_switching;
        }

        doors = 0;
    }

    writefln("Wins switching: %d [%f%%]", wins_switching,
             (wins_switching / cast(double) n) * 100);
    writefln("Wins without switching: %d [%f%%]", wins,
             (wins / cast(double) n) * 100);
}

rael@seesig.com wrote:
> In other benchmarks I've seen, D seems quite competitive with C/C++.
> 
> I seem to have written a very simple program that shows D in a very
> poor light compared to C++.  I wonder if it is my inexperience.
> 
> I am using dmd 1.0, and g++ 4.1.1 under Linux Fedora Core 6, running
> on a 3.0 GHz Pentium 4 with 1 gig of RAM.
> 
> The program is a simulation of the Monty Hall problem (see Wikipedia).
> 
> Here is the D program:
> 
> import std.random;
> import std.stdio;
> 
> void main() {
>     const uint n = 10_000_000;
>     ubyte doors;
>     uint wins, wins_switching;
> 
>     for (uint i; i < n; ++i) {
>         doors |= cast(ubyte)(1 << rand() % 3);
> 
>         if (doors & 1) {
>             ++wins;
>         } else {
>             ++wins_switching;
>         }
> 
>         doors = 0;
>     }
> 
>     writefln("Wins switching: %d [%f%%]", wins_switching,
>              (wins_switching / cast(double) n) * 100);
>     writefln("Wins without switching: %d [%f%%]", wins,
>              (wins / cast(double) n) * 100);
> }
> 
> Compiled with:
> 
> % dmd -I/opt/dmd/src/phobos -O -inline monty.d -ofmonty_d
> gcc monty.o -o monty_d -m32 -lphobos -lpthread -lm 
> 
> and here is the C++:
> 
> #include <iostream>
> #include <cstdlib>
> 
> int main() {
>     unsigned char doors = 0;
>     const unsigned int n = 10000000;
>     unsigned int wins = 0, wins_switching = 0;
> 
>     for (unsigned int i = 0; i < n; ++i) {
>         unsigned char r = 1 << (rand() % 3);
>         doors |= r; // place the car behind a random door
> 
>         if (doors & 1) { // choose zero'th door, same as random choice
>             ++wins;
>         } else {
>             ++wins_switching;
>         }
> 
>         doors ^= r; // zero the door with car
>     }
> 
>     const double d = n / 100;
>     std::cout << "Win % switching: " << (wins_switching / d)
>               << "\nWin % no switching: " << (wins / d) << '\n';
> }
> 
> Compiled with:
> 
> % g++ -O3 -o monty_cc
> 
> Execution times (best of 5):
> 
> % time monty_d
> Wins switching: 6665726 [66.657260%]
> Wins without switching: 3334274 [33.342740%]
> 
> real    0m2.444s
> user    0m2.442s
> sys     0m0.002s
> 
> % time monty_cc
> Win % switching: 66.6766
> Win % no switching: 33.3234
> 
> real    0m0.433s
> user    0m0.432s
> sys     0m0.001s
> 
> 
> Any help would be appreciated.
> 
> Thanks.
> 
> 
> Bill
> --
> Bill Lear
> r * e * @ * o * y * a * c * m
> * a * l * z * p * r * . * o *
> 
January 18, 2007
Dave wrote:
> 
> D's rand() is slow.

True. C's rand() is fast, but is known to be not very random. As you pointed out, D users can use either as required.
January 18, 2007
"Walter Bright" <newshound@digitalmars.com> wrote in message news:eoomm5$20qk$1@digitaldaemon.com...
> Dave wrote:
>>
>> D's rand() is slow.
>
> True. C's rand() is fast, but is known to be not very random. As you pointed out, D users can use either as required.

This might solve the performace in this case, but Walter, have you checked the thread "Why is this D code slower than C++" in digitalmars.D.learn ?

It's comparing DMD to DMC, and DMD's exe takes more than twice as long to complete than DMC's. Compiler flags, GC, the obvious things have been checked. Your insight would be appreciated.

L.


January 18, 2007
Kirk McDonald <kirklin.mcdonald@gmail.com> writes:

> rael@seesig.com wrote:
> > Compiled with:
> > % dmd -I/opt/dmd/src/phobos -O -inline monty.d -ofmonty_d
> 
> Perhaps the -release flag would make a difference?
> 
> Also, that -I option should be redundant if you've set up your dmd.conf file properly.

Compiling with -release seems to make no appreciable difference.

And, I have tried and tried to set up my dmd.conf file:

% ls -l /etc/dmd.conf
% cat /etc/dmd.conf
[Environment]

DFLAGS=-I/opt/dmd/src/phobos

But it doesn't seem to work.  Do you see anything I've done wrong here? This, in fact, is driving me nuts...


Bill
--
Bill Lear
r * e * @ * o * y * a * c * m
* a * l * z * p * r * . * o *
January 18, 2007
Pragma <ericanderton@yahoo.removeme.com> writes:

> rael@seesig.com wrote:
> > In other benchmarks I've seen, D seems quite competitive with C/C++. I seem to have written a very simple program that shows D in a very poor light compared to C++.  I wonder if it is my inexperience.
> [snip]
> > Any help would be appreciated.
> 
> I'm gobsmacked.  No array concatenation, strings, large allocations, or even floating point.  Just integer math and comparisons.
> 
> Check the obvious stuff first: disable the GC, compile with "-inline -release" for GDC to match the "-O3 -o" that you're using on GCC.

Hmm, tried -release and -O -inline, but not disable GC.  I'll throw a spare whirl that way and see how that goes.

> The only part of that loop that is of any consequence is the call to rand() - odds are they are two completely different algorithms, with D's being slower (performance test anyone?).  Everything else should reduce to almost the same exact machine code.

The rand() call is definitely the most expensive.  When I remove it from both the C++ and the D program, the times plummet (to 0.003 and 0.013 seconds, respectively --- still, however, leaving the D program running in 4.3 times that of the C++ program;-).


Bill
--
Bill Lear
r * e * @ * o * y * a * c * m
* a * l * z * p * r * . * o *
January 18, 2007
Bill Lear wrote:
> Kirk McDonald <kirklin.mcdonald@gmail.com> writes:
> 
>> rael@seesig.com wrote:
>>> Compiled with:
>>> % dmd -I/opt/dmd/src/phobos -O -inline monty.d -ofmonty_d
>> Perhaps the -release flag would make a difference?
>>
>> Also, that -I option should be redundant if you've set up your
>> dmd.conf file properly.
> 
> Compiling with -release seems to make no appreciable difference.
> 
> And, I have tried and tried to set up my dmd.conf file:
> 
> % ls -l /etc/dmd.conf
> % cat /etc/dmd.conf
> [Environment]
> 
> DFLAGS=-I/opt/dmd/src/phobos
> 
> But it doesn't seem to work.  Do you see anything I've done wrong here?
> This, in fact, is driving me nuts...
> 
> 
> Bill
> --
> Bill Lear
> r * e * @ * o * y * a * c * m
> * a * l * z * p * r * . * o *

Here is the dmd.conf search path (as documented on http://www.digitalmars.com/d/dcompiler.html):

1. current working directory
2. $HOME
3. the directory the dmd executable is in
4. /etc/dmd.conf

If you simply extracted the dmd archive into /opt, then it will find the dmd.conf file alongside the binary before it finds the one at /etc/dmd.conf. Either remove the one next to the binary or edit it.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
January 18, 2007
Dave <Dave_member@pathlink.com> writes:
> D's rand() is slow.
> 
> //import std.random;
> extern (C) int rand();
> import std.stdio;
> import std.conv;
>[...]

Wow, what a difference!

Now D is 0.623 seconds.  Huge difference.  Many thanks for solving this mystery for me.


Bill
--
Bill Lear
r * e * @ * o * y * a * c * m
* a * l * z * p * r * . * o *

« First   ‹ Prev
1 2 3