所以大学的一位教授刚刚告诉我,在 C# 中对字符串使用连接(即当你使用加号运算符时)会产生内存碎片,我应该使用 string.Format 代替。
不,您应该做的是进行用户研究,设置以用户为中心的实际性能指标,并根据这些指标衡量程序的性能。 当且仅当您发现性能问题时,您应该使用适当的分析工具来确定性能问题的原因。如果原因是“内存碎片”,那么通过识别“碎片”的原因并尝试实验来确定哪些技术可以减轻这种影响来解决这个问题。
性能不是通过“避免字符串连接”之类的“技巧和窍门”来实现的。性能是通过将工程学科应用于现实问题来实现的。
为了解决您更具体的问题:出于性能原因,我从未听说过避免串联以支持格式化的建议。通常给出的建议是避免迭代连接,而支持builder。迭代连接在时间和空间上是二次的,并且会产生收集压力。构建器分配不必要的内存,但在典型场景中是线性的。两者都不会产生托管堆的碎片;迭代连接往往会产生连续的垃圾块。
我遇到的性能问题归结为托管堆不必要的碎片的次数恰好是一次。在 Roslyn 的早期版本中,我们有一个模式,我们会分配一个小的长寿命对象,然后是一个小的短寿命对象,然后是一个小的长寿命对象......连续几十万次,以及由此产生的最大碎片堆对集合造成影响用户的性能问题;我们通过仔细测量相关场景中的性能来确定这一点,而不是通过对我们舒适椅子上的代码进行临时分析来确定这一点。
通常的建议不是避免碎片化,而是避免压力。我们在 Roslyn 的设计过程中发现,一旦我们前面提到的分配模式问题得到解决,压力对 GC 性能的影响远大于碎片。
我给你的建议是要么向你的教授寻求解释,要么找一位对绩效指标有更严格方法的教授。
现在,说了这么多,您应该使用格式而不是连接,但不是出于性能原因。相反,为了代码的可读性、可本地化和类似的风格问题。可以将格式字符串制成资源,可以将其本地化,等等。
最后,我提醒您,如果您将字符串放在一起以构建类似 SQL 查询或 HTML 块以提供给用户的内容,那么您不想使用这些技术。当您弄错时,这些字符串构建应用程序会产生严重的安全影响。使用专门为构建这些对象而设计的库和工具,而不是使用字符串滚动您自己的。