Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将长日志行拆分为两行时出现性能问题_Java_String_Concatenation - Fatal编程技术网

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
}