【发布时间】:2010-10-03 15:18:29
【问题描述】:
在我的 C# 应用程序中,我有一个大型结构(176 字节),每秒可能向函数传递十万次。然后,此函数只需获取指向结构的指针并将指针传递给非托管代码。函数和非托管代码都不会对结构进行任何修改。
我的问题是,我应该通过值还是通过引用将结构传递给函数?在这种特殊情况下,我的猜测是通过引用传递比将 176 个字节推入调用堆栈要快得多,除非 JIT 碰巧认识到该结构从未被修改过(我的猜测是它无法识别这一点,因为结构的地址被传递给非托管代码)并优化代码。
既然我们在这里,让我们也回答更一般的情况,即函数不将结构的指针传递给非托管代码,而是对结构。通过引用传递结构会更快吗?在这种情况下,JIT 是否会认识到该结构从未被修改并因此进行优化?据推测,通过引用传递一个 1 字节的结构不是更有效,但是在多大的结构大小下,通过引用传递一个结构会变得更好,如果有的话?
谢谢。
编辑:
如下所述,还可以创建一个“等效”类以供常规使用,然后在传递给非托管代码时使用结构。我在这里看到两个选项:
1) 创建一个仅包含该结构的“包装器”类,然后在必要时将指向该结构的指针固定并传递给非托管代码。我看到的一个潜在问题是固定有其自身的性能影响。
2) 创建一个等效类,当需要结构体时,其字段被复制到结构体中。但是复制会花费很多时间,而且在我看来,首先要打破通过引用传递的意义。
编辑:
正如下面多次提到的,我当然可以衡量每种方法的性能。我将这样做并发布结果。但是,我仍然有兴趣从知识的角度看待人们的答案和推理。
【问题讨论】:
-
有趣的问题。当然,明显的反应是每个人的情况都不一样,你不应该过早地优化,如果你想提高性能,你应该分析你的应用程序。也就是说,我很好奇一些真实的答案。
-
这是一个相当大的结构,为什么不把它转换成一个类呢?如果您要通过 ref 传递它,那么无论如何它都会破坏使其成为结构的目的。
-
指向该结构的指针被直接传递给硬件设备驱动程序,所以是的,它确实需要是一个结构。我认为,将其保留为结构并简单地获取指向它的指针比编组等效对象要快得多。
-
如果它没有被修改,我不得不期望对象的单个固定实例会快得多。更不用说结构对 x64 JITter 造成的不良影响了。
标签: c# .net optimization