Zee*_*han 11 java string optimization string-concatenation pmd
我正在通过PMD规则AppendCharacterWithChar
.它说避免在StringBuffer.append中将字符串联为字符串.
StringBuffer sb = new StringBuffer();
// Avoid this
sb.append("a");
// use instead something like this
StringBuffer sb = new StringBuffer();
sb.append('a');
Run Code Online (Sandbox Code Playgroud)
我真的需要这个PMD规则吗?以下两段代码之间有很大的性能差异吗?
String text = new StringBuffer().append("some string").append('c').toString();
String text = new StringBuffer().append("some string").append("c").toString();
Run Code Online (Sandbox Code Playgroud)
icz*_*cza 13
将一个字符附加为一个char
将永远比将其添加为一个更快String
.
但性能差异是否重要?如果你只做一次,它就不会.如果它在一个循环内重复它的身体一百万次,那么是的,它可能很重要.
如果您已在编译时拥有该字符,则只需将其作为字符附加.如果它存储在一个带有String
类型的变量中,请不要费心访问它,例如用String.charAt(0)
其他方式,只需添加即可String
.
在旁注:
赞成StringBuilder
上课StringBuffer
.StringBuilder
更快,因为它的方法不同步(在大多数情况下你不需要).
在旁注#2:
这不会编译:
String text = new StringBuffer().append("some string").append('c');
Run Code Online (Sandbox Code Playgroud)
append()
StringBuffer
链接返回.你需要打电话toString()
:
String text = new StringBuffer().append("some string").append('c').toString();
Run Code Online (Sandbox Code Playgroud)
出于好奇,我使用 jmh 运行了一个微基准测试(包括 GC 监控)。使用字符串稍微慢一些,但差异很小:每次调用大约 5 ns(纳秒),并且 GC 活动没有显着差异。
\n\n如果您调用的次数append("c")
不是append(\'c\')
一百万次,则会给您的程序增加 5 毫秒。
基准测试结果,包括 gc 时间 -n
表示 StringBuilder 的初始长度:
Benchmark (n) Mode Cnt Score Error Units\nSO28344.appendChar 0 avgt 30 16.476 \xc2\xb1 0.331 ns/op\nSO28343294.appendChar:\xc2\xb7gc.time 0 avgt 30 256.000 ms\nSO28343294.appendString 0 avgt 30 22.048 \xc2\xb1 0.345 ns/op\nSO28343294.appendString:\xc2\xb7gc.time 0 avgt 30 220.000 ms\n\nSO28343294.appendChar 50 avgt 30 17.323 \xc2\xb1 0.967 ns/op\nSO28343294.appendChar:\xc2\xb7gc.time 50 avgt 30 67.000 ms\nSO28343294.appendString 50 avgt 30 20.944 \xc2\xb1 1.466 ns/op\nSO28343294.appendString:\xc2\xb7gc.time 50 avgt 30 74.000 ms\n\nSO28343294.appendChar 1000 avgt 30 58.396 \xc2\xb1 0.811 ns/op\nSO28343294.appendChar:\xc2\xb7gc.time 1000 avgt 30 25.000 ms\nSO28343294.appendString 1000 avgt 30 64.572 \xc2\xb1 4.779 ns/op\nSO28343294.appendString:\xc2\xb7gc.time 1000 avgt 30 24.000 ms\n
Run Code Online (Sandbox Code Playgroud)\n\n代码:
\n\n@State(Scope.Thread)\n@BenchmarkMode(Mode.AverageTime)\npublic class SO28343294 {\n\n @Param({"0", "50", "1000"}) int n;\n Random r = new Random();\n StringBuilder sb;\n String s;\n char c;\n\n @Setup(Level.Invocation) public void populate() {\n sb = new StringBuilder(n + 5);\n for (int i = 0; i < n; i++) {\n sb.append((char) (r.nextInt(26) + \'a\'));\n }\n c = (char) (r.nextInt(26) + \'a\');\n s = new String(new char[] { c });\n }\n\n @Benchmark public StringBuilder appendString() {\n return sb.append(s);\n }\n\n @Benchmark public StringBuilder appendChar() {\n return sb.append(c);\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n