Meh*_*lik 3 java performance stringbuilder jvm tostring
今天我正在阅读Antonio的博客关于toString()的表现,还有一段:
曾经被认为是邪恶的昨天("不要用+ !!!连接字符串"),已经变得很酷和高效!今天,JVM将+符号编译为字符串构建器(在大多数情况下).所以,不要犹豫,使用它.
现在我很困惑,因为他说今天JVM将+符号编译成字符串构建器(在大多数情况下),但我以前从未听过或看过(代码)这样的事情.
有人可以举例说明JVM是做什么的,以及它在什么条件下发生?
Tho*_*ger 13
规则
"不要用+ !!!连接字符串"
是错的,因为它不完整,因此具有误导性.
规则是
不要在循环中将字符串与+连接
这条规则仍然有效.最初的规则从未打算在循环之外应用!
一个简单的循环
String s = "";
for (int i = 0; i < 10000; i++) { s += i; }
System.out.println(s);
Run Code Online (Sandbox Code Playgroud)
仍然比...慢得多
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) { sb.append(i); }
System.out.println(sb.toString());
Run Code Online (Sandbox Code Playgroud)
因为Java编译器必须将第一个循环转换为
String s = "";
for (int i = 0; i < 1000; i++) { s = new StringBuilder(s).append(i).toString(); }
System.out.println(s);
Run Code Online (Sandbox Code Playgroud)
索赔
今天,JVM将+符号编译为字符串构建器(在大多数情况下).
至少是误导,因为这个翻译已经用Java 1.0完成了(好吧,不是使用StringBuilder而是使用StringBuffer,因为StringBuilder只是添加了Java5).
人们也可以争辩说这个说法
今天,JVM将+符号编译为字符串构建器(在大多数情况下).
是完全错误的,因为编译不是由JVM完成的.它由Java编译器完成.
对于这个问题:Java编译器StringBuilder.append()何时使用以及何时使用其他机制?
Java编译器(版本1.8)的源代码包含两个+处理字符串通过运算符进行处理的地方.
StringBuilder结论是,对于来自OpenJDK的Java编译器(这意味着由Oracle分发的编译器),在大多数情况下,该短语总是意味着.(虽然这可能会随着Java 9而改变,或者可能是另一个像Eclipse中包含的Java编译器使用其他机制的Java编译器).
霍尔格是正确的,他的评论在Java中,9 +为字符串连接将会从改变StringBuilder到由JRE选择的策略通过invokedynamic。String concatenationjdk-9 有6种可能的策略:
private enum Strategy {
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder}.
*/
BC_SB,
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder};
* but trying to estimate the required storage.
*/
BC_SB_SIZED,
/**
* Bytecode generator, calling into {@link java.lang.StringBuilder};
* but computing the required storage exactly.
*/
BC_SB_SIZED_EXACT,
/**
* MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
* This strategy also tries to estimate the required storage.
*/
MH_SB_SIZED,
/**
* MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
* This strategy also estimate the required storage exactly.
*/
MH_SB_SIZED_EXACT,
/**
* MethodHandle-based generator, that constructs its own byte[] array from
* the arguments. It computes the required storage exactly.
*/
MH_INLINE_SIZED_EXACT
}
Run Code Online (Sandbox Code Playgroud)
并且默认的是不使用StringBuilder,它是MH_INLINE_SIZED_EXACT。实际上,实现的工作原理非常疯狂,并且正在高度优化。
因此,据我所知,那里没有任何建议是不好的。顺便说一句,这是Aleksey Shipilev由jdk所做的主要努力。他还对jdk-9中的String内部进行了很大的更改,因为它们现在由a byte[]代替char[]。之所以需ISO_LATIN_1要这样做,是因为可以将字符串编码为单个字节(一个字符-一个字节),从而减少了很多空间。
| 归档时间: |
|
| 查看次数: |
3139 次 |
| 最近记录: |