为啥字符串-字符串连接比字符串长连接更快? [关闭]
Posted
技术标签:
【中文标题】为啥字符串-字符串连接比字符串长连接更快? [关闭]【英文标题】:Why is String-String concatenation quicker than String-long concatenation? [closed]为什么字符串-字符串连接比字符串长连接更快? [关闭] 【发布时间】:2020-12-18 04:38:00 【问题描述】:在Java
中,代码如下:
long x = 123;
String s = "abc" + x;
运行时间明显长于:
long x = 123;
String s = "abc" + String.valueOf(x);
我是通过 leetcode 了解到的。我试图解决以下问题:https://leetcode.com/problems/fraction-to-recurring-decimal/
这是我的解决方案的确切代码:
public String fractionToDecimal(int numerator, int denominator)
long n = numerator, d = denominator;
boolean isNegative = (n * d < 0);
if(n < 0) n = -n;
if(d < 0) d = -d;
long q = n / d;
long r = n % d;
if(r == 0) return (isNegative ? "-" : "") + q;
StringBuilder sb = new StringBuilder();
if(isNegative) sb.append('-');
sb.append(q).append('.');
Map<Long, Integer> found = new HashMap<>();
int index = sb.length();
while(r > 0 && !found.containsKey(r))
found.put(r, index++);
n = r * 10;
q = n / d;
r = n % d;
sb.append(q);
if(r > 0)
sb.insert(found.get(r), "(");
sb.append(')');
return sb.toString();
当我点击 Submit
时,需要 7 毫秒 才能完成。
但如果我真的只是改变行号。 8 从+ q
到+ String.valueOf(q)
运行时间下降到仅1 毫秒。如有必要,请随意将代码复制粘贴到 leetcode 上进行尝试,并在运行时亲自查看此更改。
这让我非常困惑。为什么会这样?据我了解,在这两种情况下,编译器首先将 long 转换为字符串,然后将这两个字符串连接在一起,对吗?那么,在幕后,连接一个 String 和一个 long 与连接两个 String 完全一样吗?那么为什么一个比另一个需要更多的时间来运行呢?任何见解将不胜感激。 TIA。
【问题讨论】:
你的微基准测试结果在哪里证明你的断言? 您如何得出明显不同的时间安排的结论?你是如何测量的,你的数字是多少?你知道,在 Java 中进行正确的基准测试是很困难的...... @f1sh:我会在一纳秒内下注。第一个在执行时不涉及任何连接,第二个是。 您现在已经对问题进行了重大更改,因此我的回答没有任何意义。请不要那样做。 我也无法在 Leetcode 上重现你的结果。您的解决方案对我来说始终显示为 0ms。我刚刚尝试引入一个循环,因此它实际上会在返回结果之前评估结果 100,000 次...此时它需要 25-50 毫秒(不一致,并且仍然不足以作为基准测试)但它仍然 没有显示您所描述的行为。 【参考方案1】:注意:此答案是在更改问题之前编写的。它曾经包含如下所示的表达式。
"abc" + 123
是一个常量表达式 - 连接是在编译时完成的,因此“abc123”最终会出现在常量池中。
"abc" + String.valueOf(123)
不是一个常量表达式。连接发生在执行时,这显然比仅使用编译时连接结果更昂贵。
所以我希望结果与您在问题中实际报告的结果相反。
【讨论】:
好吧,OP 声称与 Jon 所说的完全相反。尽管 Jon 的解释当然是 100 正确的。 @GhostCat:哦,很好看——我没注意到。我想知道这是否只是问题中的一个错字。 但这是史诗般的问题,其中问题得到了 6 个反对票,而答案得到了 6 个赞成票。如果我们喜欢这个答案,那么可能提出的问题也是正确的。 @Hades:如果他们只是混淆了哪个版本需要更长的时间,那么最初提出的问题是有道理的。随着变化,它没有多大意义。 抱歉,Jon 和其他所有人对我的问题感到困惑。我将其编辑为正确的代码。 int 已更改为 long。并且该值不是直接添加的,而是现在通过变量添加的。愚蠢的我认为这些更改无关紧要,所以我在不知不觉中最终使代码变得比需要的更简单,以至于它改变了内部流程本身。无论如何,我已经编辑了它,并重新打开了,所以如果可能的话,请随时帮助我,尽管也许你们太生气了,不再关心了。但如果可能,请随时提供帮助。再次抱歉...以上是关于为啥字符串-字符串连接比字符串长连接更快? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 itertools.chain 比扁平化列表理解更快?
为啥 App.config 存储连接字符串的位置比源代码中更安全?