views:

308

answers:

2

In C# .NET, what is the fastest way to initialize an array of doubles to NaN?

Here is how I am presently initializing an array with many elements.

int length = array.Length;
for(int i = 0; i < length; i++)
{
    array[i] = double.NaN;
}

Is there a faster way?

A: 

You can multithread it, but it is still an O(N) problem.

Yuriy Faktorovich
+1  A: 

Filling the array with byte values of 0xff produces NaN. Try this code to see what is fastest on your machine. Memset() is not always a slam-dunk btw:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

class Program {
  static void Main(string[] args) {
    var arr = new double[10 * 1024 * 1024];
    for (int loop = 1; loop < 20; ++loop) {
      var sw1 = Stopwatch.StartNew();
      for (int ix = 0; ix < arr.Length; ++ix)
        arr[ix] = double.NaN;
      sw1.Stop();
      var sw2 = Stopwatch.StartNew();
      memset(arr, 0xff, 8 * arr.Length);
      sw2.Stop();
      Console.WriteLine("Loop: {0}, memset: {1}", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds);
    }
    Console.ReadLine();
  }
  [DllImport("msvcrt.dll")]
  private static extern void memset(double[] array, int value, int cnt);
}
Hans Passant
I *really* wish there was an intrinsic method in C# that emitted the `initblk` opcode, or at least a static method in `mscorlib` that the JIT knew to always treat as an initblk instruction.
280Z28
Did you run this code? Don't forget to use the Release build and don't run in the debugger. Swapping the two sections had a very interesting effect on my machine.
Hans Passant
@nobugz: Was that directed to me? I was just saying `initblk` is a CIL opcode that is effectively `memset` except it avoids the P/Invoke and it's likely heavily optimized into the CLR.
280Z28