为啥字符串-字符串连接比字符串长连接更快? [关闭]

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 存储连接字符串的位置比源代码中更安全?

为啥字符串连接在 C++ 中得到奇怪的结果? [关闭]

为啥一根长字符串比许多小字符串占用更多空间?

为啥对三个表的联合 mysql 查询比在不可能的 where 子句上连接更快?

为啥执行存储过程比脚本中的 SQL 查询更快?