真正的不安全代码性能

我知道不安全的代码更适合访问Windows API之类的东西并进行不安全的类型转换,而不是编写更高性能的代码,但我想问你是否注意到使用它时在实际应用程序中有任何显着的性能改进与安全的c#代码相比。

一些性能测量

性能优势并不像您想象的那么大。

我对C#中的不安全指针进行了正常托管arrays访问和性能测量。


使用Any CPU |在Visual Studio 2010,.NET 4之外的构建运行的结果 发布基于以下PC规范: 基于x64的PC,1个四核处理器。 Intel64 Family 6 Model 23 Stepping 10 GenuineIntel~2833 Mhz

 Linear array access 00:00:07.1053664 for Normal 00:00:07.1197401 for Unsafe *(p + i) Linear array access - with pointer increment 00:00:07.1174493 for Normal 00:00:10.0015947 for Unsafe (*p++) Random array access 00:00:42.5559436 for Normal 00:00:40.5632554 for Unsafe Random array access using Parallel.For(), with 4 processors 00:00:10.6896303 for Normal 00:00:10.1858376 for Unsafe 

请注意,不安全的*(p++)习惯用法实际上运行速度较慢。 我的猜测打破了编译器优化,即在安全版本中将循环变量和(编译器生成的)指针访问相结合。

github上提供的源代码。

正如其他post中所述,您可以在非常专业的环境中使用不安全的代码来获得显着的性能提升。 其中一种情况是迭代值类型的数组。 使用不安全的指针算法比使用for-loop / indexer的常用模式要快得多。

 struct Foo { int a = 1; int b = 2; int c = 0; } Foo[] fooArray = new Foo[100000]; fixed (Foo* foo = fooArray) // foo now points to the first element in the array... { var remaining = fooArray.length; while (remaining-- > 0) { foo->c = foo->a + foo->b; foo++; // foo now points to the next element in the array... } } 

这里的主要好处是我们完全删除了数组索引检查。

虽然性能非常高,但这种代码很难处理,可能非常危险(不安全),并且破坏了一些基本的指导原则(可变结构)。 但是有一些情况确实适合……

一个很好的例子是图像处理。 通过使用指向其字节的指针(需要不安全的代码)来修改像素要快得多。

示例: http : //www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx

话虽如此,对于大多数情况来说,差异并不明显。 因此,在使用不安全的代码之前,请对应用程序进行概要分析,以了解性能瓶颈的位置,并测试不安全的代码是否真的是使其更快的解决方案。

好吧,我建议阅读这篇博文: MSDN博客:CLR中的数组边界检查消除

这阐明了如何在C#中完成边界检查。 此外,Thomas Bratts测试似乎对我无用(查看代码),因为JIT在他的’save’循环中删除了绑定检查。

我正在使用不安全的代码来处理video操作代码。 在这样的代码中,您希望它尽可能快地运行,而无需对值进行内部检查等。如果没有不安全的属性,我可能无法以30fps或60 fps跟上video流。 (取决于使用过的相机)。

但由于速度,它被代码图形的人广泛使用。