将数组中的所有元素初始化为 NaN 的最快方法是啥?
Posted
技术标签:
【中文标题】将数组中的所有元素初始化为 NaN 的最快方法是啥?【英文标题】:What is the fastest way to initialize all elements in an array to NaN?将数组中的所有元素初始化为 NaN 的最快方法是什么? 【发布时间】:2011-01-19 04:52:53 【问题描述】:在 C# .NET 中,将双精度数组初始化为 NaN 的最快方法是什么?
这是我目前如何初始化一个包含许多元素的数组。
int length = array.Length;
for(int i = 0; i < length; i++)
array[i] = double.NaN;
有没有更快的方法?
【问题讨论】:
我喜欢 'Enumerable.Repeat(defaulValue, arrayLength).ToArray()'(从 .NET 3.5 开始可用) 如果你在 Linux 上,内存映射 my device driver 会返回以双精度数组形式填充 NaN 的写时复制页面。 O(1) 无论数组大小如何! 【参考方案1】:用 0xff 的字节值填充数组会产生 NaN。试试这个代码,看看你的机器上什么是最快的。顺便说一句,Memset() 并不总是扣篮:
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);
【讨论】:
我真的希望 C# 中有一个内部方法可以发出initblk
操作码,或者至少是 mscorlib
中的一个静态方法,JIT 知道它总是会处理作为 initblk 指令。
你运行了这段代码吗?不要忘记使用 Release 构建并且不要在调试器中运行。交换这两个部分对我的机器产生了非常有趣的影响。
这是针对我的吗?我只是说initblk
是一个 CIL 操作码,它实际上是 memset
,除了它避免了 P/Invoke 并且它可能在 CLR 中进行了大量优化。
除非有一个非常很好的理由进行这种优化,否则我更喜欢原始的for循环,因为它具有更好的可读性、可维护性和健壮性。顺便说一句,使用 memset 不需要固定数组吗?类似GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned); memset(gch.AddrOfPinnedObject(), 0xff, 8 * arr.Length);
pinvoke marshaller 自动固定数组。【参考方案2】:
你可以多线程,但这仍然是一个 O(N) 问题。
【讨论】:
以上是关于将数组中的所有元素初始化为 NaN 的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章