Java 将长日志行拆分为两行时出现性能问题
当我们为了可读性将一长行代码一分为二时,它会在行之间引入一个加号(如果在文本之间拆分)。 例如,在文本中间拆分一条长线,这将记录一些文本Java 将长日志行拆分为两行时出现性能问题,java,string,concatenation,Java,String,Concatenation,当我们为了可读性将一长行代码一分为二时,它会在行之间引入一个加号(如果在文本之间拆分)。 例如,在文本中间拆分一条长线,这将记录一些文本 所以,考虑到它在图片中带来的额外字符串连接,应该避免这种情况吗?或者更好的可读性权衡的权重更高?是的,有一点性能影响。常规编译器不进行任何优化。它只是用StringBuilder方法调用替换+运算符。例如,如果您有字符串s=“x”+“y”+“z”,它可以替换为字符串s=new StringBuilder().append(“x”).append(“y”).ap
所以,考虑到它在图片中带来的额外字符串连接,应该避免这种情况吗?或者更好的可读性权衡的权重更高?是的,有一点性能影响。常规编译器不进行任何优化。它只是用
StringBuilder
方法调用替换+运算符。例如,如果您有字符串s=“x”+“y”+“z”代码>,它可以替换为字符串s=new StringBuilder().append(“x”).append(“y”).append(“z”)代码>在编译成字节码之前。但这里没有真正的优化。它不会替换为String s=“xyz”代码>生成字节码之前。我不确定JIT编译器是否在生成本机处理器指令之前对其进行了优化。但即使是这样,它在运行时也会对性能造成微小的影响
就我个人而言,如果它们以微小的性能损失为代价的话,我会更加注重优雅和可读性 所有常见的Java编译器都过于成熟,无法在运行时执行诸如连接字符串文本之类的愚蠢操作。让我们检查一下。鉴于此代码:
public class CatStrings {
public static void main(String [] args) {
String a = "This is a long long long string broken up "
+ "into parts to see if the compiler "
+ "optimizes the concatenation.";
System.out.println(a);
}
}
我的Java 8编译器-Oracle标准-做了正确的事情,如javap
output所示:
stack=2, locals=2, args_size=1
0: ldc #2 // String This is a long long long string broken up into parts to see if the compiler optimizes the concatenation.
2: astore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
视情况而定
如果只有常量,javac会处理它。以下节目:
public class Main {
public static void main(String[] args) {
System.out.println("foo"+"bar");
}
}
转换为以下字节码(删除了一些不相关的部分):
你可以在那里看到foobar常量。因此,在这种情况下,不会对性能造成影响
但是,如果我们将计划更改为更现实的计划:
public class Main {
public static void main(String[] args) {
int a = 1;
System.out.println(a+"foo" + "bar");
}
}
我们得到以下字节码:
public class com/hazelcast/Main {
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
ICONST_1
ISTORE 1
L1
LINENUMBER 10 L1
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ILOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
LDC "foo"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC "bar"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L2
LINENUMBER 11 L2
RETURN
L3
LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
LOCALVARIABLE a I L1 L3 1
MAXSTACK = 3
MAXLOCALS = 2
}
公共类com/hazelcast/Main{
//访问标志0x9
公共静态main([Ljava/lang/String;)V
L0
9号线L0
ICONST_1
史前1
L1
线路号10 L1
GETSTATIC java/lang/System.out:Ljava/io/PrintStream;
新java/lang/StringBuilder
重复
调用特殊的java/lang/StringBuilder。()V
伊洛德1号
invokeVirtualJava/lang/StringBuilder.append(I)Ljava/lang/StringBuilder;
最不发达国家“富”
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
最不发达国家“酒吧”
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokeVirtualJava/lang/StringBuilder.toString()Ljava/lang/String;
INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/String;)V
L2
行号11 L2
返回
L3
LOCALVARIABLE args[Ljava/lang/String;L0 L3 0
本地变量a I L1 L3 1
MAXSTACK=3
最大局部数=2
}
如您所见,“foo”和“bar”不会自动连接
我不知道JIT是否能够删除不需要的连接。我大约99%确定编译器会将其转换为一个漂亮的大字符串文字,以便youGene或pveentjer的答案可能应该标记为正确的答案。Downvoter,是否要解释你对这个答案的憎恨?
public class com/hazelcast/Main {
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
ICONST_1
ISTORE 1
L1
LINENUMBER 10 L1
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ILOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
LDC "foo"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC "bar"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L2
LINENUMBER 11 L2
RETURN
L3
LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
LOCALVARIABLE a I L1 L3 1
MAXSTACK = 3
MAXLOCALS = 2
}