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