【发布时间】:2017-09-19 04:28:14
【问题描述】:
我进行了一些研究,似乎普遍认为结构应该小于 16 个字节,否则它们会因复制而导致性能损失。使用 C#7 和 ref return,完全避免复制结构变得非常容易。我假设随着结构体的大小变小,通过 ref 传递比复制值有更多的开销。
当按值传递结构比按引用更快时,是否有经验法则?哪些因素会影响这一点? (结构体大小、进程位数等)
更多上下文
我正在开发一款游戏,其中绝大多数数据表示为连续的结构数组,以实现最大的缓存友好性。正如您可能想象的那样,在这种情况下传递结构是很常见的。我知道分析是确定某事物的性能影响的唯一真正方法。但是,我想了解它背后的理论概念,并希望在编写代码时考虑到这种理解并仅分析边缘情况。
另外,请注意,我不是在询问最佳实践或通过 ref 传递所有内容的合理性。我知道“最佳做法”和影响,我故意选择不遵循它们。
解决“重复”标签
Performance of pass by value vs. pass by reference in C# .NET - 这个问题讨论了通过 ref 传递引用类型,这与我的要求完全不同。
In .Net, when if ever should I pass structs by reference for performance reasons? - 第二个问题有点触及主题,但它与结构的特定大小有关。
回答Eric Lippert's article的问题:
你真的需要回答这个问题吗?是的,我需要。因为它会影响我写很多代码的方式。
这真的是瓶颈吗?可能不是。但我仍然想知道,因为这是 99% 的程序的数据访问模式。在我看来,这类似于选择正确的数据结构。
差异是否相关?是的。通过 ref 传递大型结构更快。我只是想了解它的局限性。
您所说的“更快”是什么意思?就像为同一任务减少 CPU 的工作量一样。
你在看大局吗?是的。如前所述,它会影响我写整个东西的方式。
我知道我可以测量很多不同的组合。那告诉我什么?在我的 [.NET 版本、进程位数、操作系统、CPU] 的组合中,X 比 Y 快。 Linux 呢?安卓呢? iOS 呢?我应该对所有可能的硬件/软件组合的所有排列进行基准测试吗?
我认为这不是一个可行的策略。因此,我在这里问,希望对 CLR/JIT/ASM/CPU 有很多了解的人可以告诉我它是如何工作的,这样我就可以在编写代码时做出明智的决定。
我正在寻找的答案类似于前面提到的 16 字节结构大小指南,并解释了原因。
【问题讨论】:
-
第二个问题的答案归结为何时使用结构,何时不使用。我有一个真实的场景,我的几乎所有数据都表示为大小差异很大的结构。
-
你显然完全没有抓住重点。我没有复制任何东西,因为我是通过 ref 传递和返回的。
-
我的问题中标记为粗体的部分有什么含义?我敢肯定,了解 CLR 和 JITter 内部工作原理的人可以用 2 句话明确回答。问题的其余部分旨在描述我的场景与您所链接的问题中的场景有何不同。
-
这只是你的意见。因为我仍然想得到我的答案——我有什么选择?既然已经结束,我怎样才能让更了解该主题的人看到这个问题?编辑它?举报?
-
这实际上是一个相关的问题。对于 99% 的程序,我认为这完全是愚蠢的——但如果你做一个内部游戏循环,或者即交易后端的自动收报机,这就是真正出现并产生差异的问题类型。如果您考虑跨度,它会变得更加相关,这样您就可以在不复制的情况下移动视图/数组的一部分。我个人有一些程序,其中核心循环大约是 3 页代码,使用 95% 的处理时间和 - 运行循环更新数组中的值,这些值出于性能原因表示为结构。好问题。
标签: c# performance struct ref