.NET与Java之间子串操作性能的比较

pol*_*nts 9 .net java string performance substring

获取字符串的子字符串是一种非常常见的字符串操作操作,但我听说Java和.NET平台之间的性能/实现可能存在很大差异.具体来说,我听说在Java中,java.lang.String提供恒定时间操作substring,但在.NET中,System.String提供线性性能Substring.

这些真的是这样吗?可以在文档/源代码等中确认吗?此实现是特定的,还是由语言和/或平台指定的?每种方法的优缺点是什么?一个人从一个平台迁移到另一个平台应该寻找什么来避免陷入任何性能陷阱?

Jon*_*eet 11

在.NET中,Substring是O(n)而不是Java的O(1).这是因为在.NET中,String对象包含所有实际的字符数据本身1 - 因此获取子字符串涉及复制新子字符串中的所有数据.在Java中,substring可以创建一个引用原始char数组的新对象,具有不同的起始索引和长度.

每种方法都有利弊:

  • .NET的方法具有更好的缓存一致性,创建更少的对象2,并避免了一个小子串阻止非常大char[]的垃圾收集的情况.我相信在某些情况下,内部也可以使互操作变得非常简单.
  • Java的方法使得子串非常有效,也可能是其他一些操作

我的弦乐文章中有更多细节.

至于避免性能缺陷的一般问题,我认为我应该准备好剪切和粘贴的固定答案:确保您的架构高效,并以最易读的方式实现它.衡量性能,并优化您发现瓶颈的位置.


1顺便说一下,这string非常特殊 - 它是唯一的非数组类型,其内存占用量在同一个CLR中实例化.

2对于小弦乐,这是一个很大的胜利.一个对象的所有开销都很糟糕,但是当涉及到额外的数组时,单字符字符串在Java中可能需要大约36个字节.(这是一个"空中手指"号码 - 我不记得确切的对象开销.它还取决于你正在使用的VM.)