gpt4 book ai didi

java - 评估赋值运算符性能与具体操作的正确测试用例是什么?

转载 作者:行者123 更新时间:2023-11-29 06:46:57 25 4
gpt4 key购买 nike

简单地说,我想弄清楚什么是快速分配一个值的方法,比如

somevar+=1;

somevar=somevar+1;

以前在使用文本而不是整数的情况下,我使用 text+="sometext" 而不是 text.append("sometext") 时遇到了一些性能下降>text=text+"sometext",问题是我再也找不到注释我的注意事项的源代码。那么理论上最快的方法是什么?

代码后台设置成快速循环,近乎实时。

最佳答案

如果你有这样的事情:

Collection<String> strings = ...;
String all = "";
for (String s : strings) all += s;

...那么它等同于:

Collection<String> strings = ...;
String all = "";
for (String s : strings) all = new StringBuilder(all).append(s).toString();

每个循环创建一个新的 StringBuilder,它本质上是 all 的副本,将 s 的副本附加到它,然后复制连接到新的 String 的结果。显然,使用单个 StringBuilder 可以节省大量不必要的分配:

Collection<String> strings = ...;
StringBuilder sb = new StringBuilder();
for (String s : strings) sb.append(s);
String all = sb.toString();

至于 x += yx = x + y,它们编译成相同的东西。

class Concat {

public String concat1(String a, String b) {
a += b;
return a;
}

public String concat2(String a, String b) {
a = a + b;
return a;
}

}

javac编译,然后用javap反汇编:

$ javap -c Concat
Compiled from "Concat.java"
class Concat extends java.lang.Object{
Concat();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return

public java.lang.String concat1(java.lang.String, java.lang.String);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
18: astore_1
19: aload_1
20: areturn

public java.lang.String concat2(java.lang.String, java.lang.String);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: aload_1
8: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: aload_2
12: invokevirtual #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: invokevirtual #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
18: astore_1
19: aload_1
20: areturn

}

就我个人而言,我更喜欢 += 因为有了它,您可以做出更清晰的意图声明 - “我想将 b 的内容添加到 一个”。两种形式之间的任何性能差异都 100% 确定是您的代码之外的结果(例如,GC 暂停、随机缓存未命中或类似情况)。

糟糕的编译器也可能更容易优化 += 形式(这与你无关,因为即使 javac 很糟糕,HotSpot 肯定是't).

关于java - 评估赋值运算符性能与具体操作的正确测试用例是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3446838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com