1
String.Substring()似乎使此代码成为瓶颈
介绍 我有一个很喜欢的算法,我很早以前就做了,我一直在用新的编程语言,平台等来编写和重新编写某种基准。尽管我的主要编程语言是C#,但是我只是从字面上复制粘贴了代码,并稍稍更改了语法,使用Java进行了构建,并发现其运行速度快了1000倍。 编码 有很多代码,但是我仅要介绍这个片段,这似乎是主要问题: for (int i = 0; i <= s1.Length; i++) { for (int j = i + 1; j <= s1.Length - i; j++) { string _s1 = s1.Substring(i, j); if (tree.hasLeaf(_s1)) ... 数据 重要的是要指出,在此特定测试中,字符串s1的长度为1百万个字符(1MB)。 测量 我之所以在Visual Studio中介绍代码执行情况,是因为我认为构造树或遍历树的方法不是最佳方法。检查结果后,该行似乎占据string _s1 = s1.Substring(i, j);了执行时间的90%以上! 其他观察 我注意到的另一个区别是,尽管我的代码是单线程的Java还是设法使用所有8个内核(100%CPU使用率)执行它,而即使使用Parallel.For()和多线程技术,我的C#代码也设法使用了35-最多40%。由于该算法随内核数(和频率)线性扩展,因此我对此进行了补偿,而Java中的代码段执行速度却快了100-1000倍。 推理 我认为发生这种情况的原因与以下事实有关:C#中的字符串是不可变的,因此String.Substring()必须创建一个副本,并且由于它位于具有多次迭代的嵌套for循环中,所以我想很多复制和正在进行垃圾收集,但是,我不知道Substring是如何在Java中实现的。 题 …