3

我认为这是连接字符串的最有效方法

new StringBuilder(s1.length() + s2.length() + s3.length()).append(s1).append(s2).append(s3).toString();

这里 StringBuilder 的缓冲区创建的容量足以容纳其中的所有字符串,否则 StringBuilder 可能需要将缓冲区扩大 3 倍。

但是当我编译/反编译这个

String s4 = s1 + s2 + s3;

我在 javac (1.7.0_03) 构建的 .class 中得到了实际代码

String s4 = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).toString();

哪种方式更有效?

更新

正如 Steven Schlansker 所建议的,这是一个性能测试

                String s1 = "0123456789";
                String s2 = s1 + s1 + s1;
                String s3 = s1 + s1 + s1 + s1 + s1 + s1;
                long t0 = System.currentTimeMillis();
                for (int i = 0; i < 500000; i++) {

                String s4 = new StringBuilder(s1.length() + s2.length() + s3.length()).append(s1).append(s2).append(s3).toString();

//          String s4 = s1 + s2 + s3;

                }
                System.out.println(System.currentTimeMillis() - t0);

它并不完美,但结果似乎证明我的版本快了约 30%。在我的笔记本(Celeron 925)上,ver.1 aganist 大约 230 ms,ver.2 大约 300 ms。其实这正是我所期望的。所以我认为如果 javac 以更有效的方式编译字符串连接将是一个好主意。有足够的线条像

return "\\Q" + s + "\\E";

即使在 JDK 类中。最后一行来自为提高效率而设计的 java.util.Pattern

4

1 回答 1

4

取决于您在其中执行它的环境。如果没有某种测试,不可能肯定地断定一个比另一个更好。

也就是说,我同意提前知道最终尺寸可能会带来一些好处。

我怀疑如果你编写一个微基准测试,你会发现几乎在任何应用程序中差异都是微不足道的。

编辑基准建议:

我看到您在帖子中添加了一些实际数据。恭喜!你在正确的轨道上:-)

不幸的是,Java 有许多不利于编写正确基准的特性。您可能应该看看如何在 Java 中编写正确的微基准测试?如果您希望结果准确。同样值得考虑的是,在这种情况下看起来很大的加速在“真实”程序的情况下看起来要小得多。单个数据库获取(以毫秒为单位)很容易使内存分配的任何收益完全无趣(以纳秒为单位)。

于 2012-12-03T06:44:44.473 回答