On 07/04/2013 03:05 PM, monarch_dodra wrote:
> Me thinks the test is biased with answering true to isNan. You should first
> initialize your arrays with random [true/false] | [nan/nonan] value. In
> particular, it is more important for isNan to answer "No" as fast as possible,
> rather than actually find nan's. (common, use case is checking that a number 
> is
> *not*) nan. I'd say a mix of 90% rands + 10% Nan's would be representative?

Quite right -- the case of isNaN being false is the case that needs to be really
quick.

> Also, there might be optimizations in bool iteration over double iteration 
> given
> their size, as well as the fact that the "first" test is typically faster.

I'd assumed that putting the start/stop of the stopwatch inside the loop would
address that, but apparently not ...

> I think you should create an array of S{bool; double;} So that the iteration 
> is
> not biased either.
> 
> I'd add a dummy "warmup" loop of 10% of the iterations too, just 'cause.

See attached.  I haven't put in the dummy warmup loop, but as is, there's
consistently less than 2ms difference between the times reported for all
compilers.  If I use rdmd without optimizations, the difference is slightly
larger at 3-5ms.

So, on the basis of that I think I feel happy about using isNaN as a test,
especially as it lets me remove an otherwise superfluous variable from
RandomSample.  Thanks for the advice! :-)
import std.datetime, std.random, std.range, std.stdio;
import std.math: isNaN;

struct S
{
    bool b;
    double d;
}

void main()
{
    auto arr = new S[1_000_000];

    foreach (ref a; arr)
    {
        a.b = false;
        a.d = double.nan;
    }

    auto sample = randomSample(iota(arr.length), 9 * arr.length / 10);
    foreach (s; sample)
    {
        arr[s].b = true;
        arr[s].d = 1.0;
    }

    StopWatch watch;
    size_t i = 0;

    foreach (a; arr)
    {
        watch.start();
        if (!a.b)
        {
            ++i;
        }
        watch.stop();
    }

    writeln("Time for ", arr.length, " if(boolean)'s with ", i, " counts of true: ", watch.peek.usecs, " microseconds.");

    watch.reset;
    i = 0;

    foreach (a; arr)
    {
        watch.start();
        if (isNaN(a.d))
        {
            ++i;
        }
        watch.stop();
    }

    writeln("Time for ", arr.length, " if(isNaN)'s with ", i, " counts of true: ", watch.peek.usecs, " microseconds.");
}

Reply via email to