C#中指针的性能和用法

时间:2013-04-30 21:49:54

标签: c# .net pointers

与仅使用托管代码相比,使用c#中的指针是否具有任何显着的性能优势?指针的最佳用例是什么?我真的没有任何具体的例子,我以前从未需要使用它们。看起来使用指针可以更快地操作数据,但最终可能只是微不足道。我甚至考虑它们的唯一原因是因为我正在创建一个Matrix类(仅限学习目的),我想尽量使所有计算尽可能高效。

6 个答案:

答案 0 :(得分:10)

  

与仅使用托管代码相比,使用c#中的指针是否具有任何显着的性能优势?

有时。

  

指针的最佳用例是什么?

极其敏感的代码,以及与现有非托管代码的互操作性。

  

我真的没有任何具体的例子,我以前从未需要使用它们。

我已经写了大约十年的C#代码了,我不记得曾经需要在实际的业务线上使用指针"码。测试用例,当然。但不适合生产。

  

我想尝试尽可能高效地进行所有计算。

我在StackOverflow上听到了很多。不,你其实并不想要。你想让它们尽可能高效给定一定的预算。例如,您可能不愿意投入数十亿美元用于新的数学芯片制造。 有些人愿意这样做,但你不是其中之一。有些人有这样的钱可以花钱和问题,如果他们有技术,他们可以获利。您可能愿意尽可能提高效率给定一定数量的现有技术给予您一定的时间和精力,您愿意投入其中。因为你的目标实际上并不是写快速数学,所以你的目标是学习如何优化程序。

在这种情况下,学习如何优化程序。优化程序的方法是使用分析工具来识别代码中的问题点,然后然后,基于数据,决定是否探索不安全代码解决方案的成本和收益。例如,可能是您的大部分成本是由于缓存未命中而您真正需要的是更好的局部性而不是更少的阵列范围检查。或者你可能会发现,对于你的问题空间,memoization是一种更好的技术。有很多方法可以让程序更快,但是如果没有数据,你就无法知道自己是否能得到更好的效果。

答案 1 :(得分:3)

这个问题没有明确的答案,但是使用带有固定结构的unsafe代码(你称之为“指针”)可以带来性能优势,例如,你在一个非常紧密的循环中循环遍历数组,需要尽可能高的速度,但不需要边界检查。您的里程数将根据您在循环中的操作而有所不同,但我通过简单地声明方法unsafe看到了10%的速度提升。

答案 2 :(得分:1)

C#中有两个主要的用例:

  1. 拥有:用于本机互操作或非托管内存数据结构。
  2. 你想摆脱数组边界检查或做一些其他无法验证的东西。
  3. 在其他情况下,它没有帮助。它对于无论如何都要消除边界检查的数组也无济于事。

    它还会损害当前JIT的代码质量,因为它没有针对原始指针进行特别优化。

    在任何情况下:了解为什么它可以提供帮助非常重要,这样您就可以预测哪些内容会有用,哪些内容无用。

    与C编译器相比,

    在C#中不安全是 nothing 。 C编译器执行JIT从未听说过的事情。它不是“C模式”。 (目前的JIT并不好,但也无济于事。)

答案 3 :(得分:1)

使用非托管代码总是会更快运行;使用托管代码总是会更快上市。需要多少非托管代码才能使您的应用程序足够快以便随后依靠硬件改进,这是一项工程权衡。

标准方法是主要用于“更快上市”,然后在事后调整关键的已知问题区域。这具有显着的优势:

  1. 编写干净的托管代码所获得的时间是“在银行中”,并且可以根据需要有效地重新聚焦以解决已知问题。
  2. 重写干净的托管代码以获得更好的性能要比恢复编写高度调整的代码所花费的时间更容易。
  3. 这里明确的推论是,倾向于编写更多托管代码比反向更安全。

答案 4 :(得分:0)

当你不受管理时,几乎所有东西都会更快。 多快取决于很多因素。选择最关键的部件并进行一些测试。

答案 5 :(得分:0)

这完全取决于您如何在不安全的块内编写代码。非托管代码具有更高的性能上限,但是,如果您没有正确编写它,性能可能会比C#默认提供的更差。例如,如果您使用指针来实现对数组中元素的更有效访问,则性能增益将会很大。如果您只是将它们用作对象的引用,那么您通常会使用Obj myObj = new Obj()进行分配,它可能不会有任何不同。