为什么 String-String 连接比 String-long 连接更快?

San*_*gya -9 java concatenation string-concatenation

Java,以下代码:

long x = 123;
String s = "abc" + x;
Run Code Online (Sandbox Code Playgroud)

花费的运行时间明显多于:

long x = 123;
String s = "abc" + String.valueOf(x);
Run Code Online (Sandbox Code Playgroud)

我是通过 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();
}
Run Code Online (Sandbox Code Playgroud)

当我点击Submit它需要长达7 毫秒才能完成。但是,如果我真的只是更改行号。8 from + qto+ String.valueOf(q)运行时间直线下降到只有1 毫秒。如有必要,请随时将代码复制粘贴到 leetcode 上进行尝试,并在运行时亲自查看此更改。

这让我非常困惑。为什么会这样?根据我的理解,在这两种情况下,编译器首先将 long 转换为 String,然后将这两个 String 连接在一起,对吗?那么,在幕后,连接一个 String 和一个 long 与将两个 String 连接在一起是不是完全一样?那么为什么一个比另一个花费更多的时间来运行呢?任何见解将不胜感激。TIA。

Jon*_*eet 7

注意:此答案是在更改问题之前编写的。它曾经包含如下所示的表达式。

"abc" + 123是一个常量表达式——连接是在编译时完成的,所以“abc123”最终会出现在常量池中。

"abc" + String.valueOf(123)不是一个常量表达式。连接发生在执行时,这显然比仅使用编译时连接结果要昂贵得多。

因此,我希望结果与您在问题中实际报告的结果相反

  • 好吧,OP 的说法与乔恩所说的完全相反。尽管 Jon 的解释当然是 100 个正确的。 (4认同)