C# 在C中,通过引用在数组中传递结构对性能有什么影响#

C# 在C中,通过引用在数组中传递结构对性能有什么影响#,c#,performance,xna,C#,Performance,Xna,我正在用C#/XNA编写一段代码,其中我非常关注性能。其中一部分是将存储在数组中的多个结构传递给各种函数 在提出这个问题之前,这些确实应该是结构,而不是类。它们本质上是值类型,它们需要(基本上)存在于堆栈上。它们有很多,它们来去很快,让垃圾收集器为它们服务(即使我在运行池)也会很昂贵 通过引用传递,我已经大大提高了性能,但我想知道当数组的同一索引处的同一个结构通过引用传递给几个不同的函数时,这会对性能产生什么影响。我假设为了使这一切都能正常工作,C#必须在传递结构之前在内部固定数组指针。我是否会

我正在用C#/XNA编写一段代码,其中我非常关注性能。其中一部分是将存储在数组中的多个结构传递给各种函数

在提出这个问题之前,这些确实应该是结构,而不是类。它们本质上是值类型,它们需要(基本上)存在于堆栈上。它们有很多,它们来去很快,让垃圾收集器为它们服务(即使我在运行池)也会很昂贵

通过引用传递,我已经大大提高了性能,但我想知道当数组的同一索引处的同一个结构通过引用传递给几个不同的函数时,这会对性能产生什么影响。我假设为了使这一切都能正常工作,C#必须在传递结构之前在内部固定数组指针。我是否会通过首先固定结构并传递指针来获得性能

比如说。如果我有类似于:

for(int i = 0; i < array.Length; ++i)
{
    value = Function1(ref array[i]);

    // Lots of code....

    otherValue = Function2(ref array[i]);

    // Lots of code....

    anotherValue = Function3(ref array[i]);
}
for(int i=0;i
难道C#本质上不需要这样做吗

for(int i = 0; i < array.Length; ++i)
{
    pin(array);
    value = Function1(ref array[i]);
    unpin(array);

    // Lots of code....

    pin(array);
    otherValue = Function2(ref array[i]);
    unpin(array);

    // Lots of code....

    pin(array);
    anotherValue = Function3(ref array[i]);
    unpin(array);
}
for(int i=0;i
我这样做会更好吗

for(int i = 0; i < array.Length; ++i)
{
    fixed(struct* working = ^array[i]) 
    {
        value = Function1(working);

        // Lots of code....

        otherValue = Function2(working);

        // Lots of code....

        anotherValue = Function3(working);
    }
}
for(int i=0;i
或者,甚至更好

fixed(struct* working = ^array[0]) 
{
    for(int i = 0; i < array.Length; ++i)
    {
        value = Function1(working[i]);

        // Lots of code....

        otherValue = Function2(working[i]);

        // Lots of code....

        anotherValue = Function3(working[i]);
    }
}
已修复(结构*working=^array[0])
{
for(int i=0;i

或者C#编译器/JITter是否足够聪明,可以自动固定数组?

您将托管引用与指针混淆了

托管引用永远不需要固定,即使它指向数组中的元素,因为GC“知道”该引用,并且在移动数组时会更新它


钉扎仅对不安全代码中的非托管指针是必要的,出于性能原因,应尽可能避免钉扎。

我不确定XNA(它是一个不同的CLR),但.NET Framework(从3.5开始)不钉扎通过引用传递的内容(默认情况下,除非它们被传递给非托管代码。如果调用GC,它仍然可以移动数据,因为堆栈会被扫描以获取引用。如果非托管代码在某个级别上运行,那么,是的,它确实需要被锁定。

+1要使点明确,在这种情况下使用
修复
会对性能产生负面影响,pos重要的是。这就是我需要知道的。谢谢!这与你的问题是正交的,但你永远不应该写“//大量的代码…”。你应该把类似的代码片段分解成它们自己的小方法。然后,让编译器为你内联这些代码。另外,对于重复访问“working[I]”的问题,DRY:和,分析代码以查找性能问题:)只有在没有算法替代方案的情况下,低级别优化才是好的。同意。显然,在实际编写的函数中实际发生的事情比示例中显示的要复杂得多。系统已经过分析,该函数是一个瓶颈,除了t之外,没有算法替代方案可以替代低级别优化o降低函数的精度。