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.");
}