Java最快的字符串、整数和浮点数拼接方法

6

如何以最高效的方式从字符串、整数和浮点数构建字符串?目前我正在使用以下方法,但它会消耗大量CPU时间。

String frame = this.frameTime + ":" +
    this.player.vertices[0].x + "," +
    this.player.vertices[0].y + "," +
    this.player.activeAnimId + "," +
    (int)this.player.virtualSpeed + "," +
    this.map.getCurrentTime() + 
    (this.player.frameSound == -1 ? "" : "," + this.player.frameSound) +
    (this.player.frameDecal.equals("") ? "" : "," + this.player.frameDecal) +
    ";";

有没有更快的方法可以实现这个?

你尝试过使用 StringBuilder 吗? - Brian Hoover
1
你尝试过使用 String.format() 吗? - Jesus is Lord
1
@BrianHoover 这里使用了 StringBuilder。 - Peter Lawrey
请查看此帖子以获取解释。http://www.rationaljava.com/2015/02/the-optimum-method-to-concatenate.html - Dan
5个回答

20

这应该已经很快了 - 它将内部使用StringBuilder进行连接。可以说,显式使用StringBuilder可以消除空字符串的连接,但这不可能使大的差异。

你到底有多频繁地这样做呢?它必须非常频繁才会成为瓶颈...你真的需要这样做那么频繁吗?

编辑:对于那些说“使用 StringBuilder,它会更快”的人,请考虑这段代码:

public class Test
{
    public static void main(String[] args)
    {
        int x = 10;
        int y = 20;
        int z = 30;
        String foo = x + "," + y + "," + z + ";";
        System.out.println(foo);
    }
}

编译它,然后使用javap -c查看编译器生成的内容...


@JavaKungFu:这并不一定是在循环中。当你使用字符串连接表达式的结果时,就会出现这种情况 - 所以如果你做了 String foo = x + ","; foo = foo + z; foo = foo + ","; 等等,那么这将是浪费的。 - Jon Skeet
1
@zolex:在这种情况下,最好根本不要构建中间字符串,而是直接将值写入“Writer”,而不是在写入之前将它们连接起来。 - Louis Wasserman
1
@zolex:哎呀,你正在使用默认编码调用 getBytes()。请不要这样做。如果您确实需要字符串表示形式,请改用 OutputStreamWriter。但是为什么不使用 DataOutputStream 仅写入要记录的二进制数据?无需进行字符串转换。 - Jon Skeet
ic,我应该使用writeUTF(),让我们试一下... ^^ - Andreas Linden
@zolex:那就使用writeUTF吧 - 这是与readUTF相匹配的调用。 - Jon Skeet
显示剩余14条评论

3
使用StringBuilder
String string = new StringBuilder("abcd").append(23).append(false).append("xyz").toString();

5
你认为这样做会更快,有什么原因吗? - Jon Skeet

2
你可以尝试使用 StringBuilder
(然而,大多数值得信赖的Java编译器都会自动优化你列出的代码,以在幕后使用 StringBuilder。)

1
如果你想让它跑得非常快,你可以尝试我的库,它允许你在不创建任何垃圾的情况下记录微秒级别的消息。https://github.com/peter-lawrey/Java-Chronicle (正如我所说,这可能对你想要的东西有些过头了)

-1

以下是concat3方法,对我来说速度最快。concat1的性能取决于JVM的实现/优化,它在其他版本的JVM上可能表现更好,但在我测试过的Windows机器和远程Linux Red Hat机器上,concat3的速度最快。

public class StringConcat {

public static void main(String[] args) {
    int run = 100 * 1000 * 1000;
    long startTime, total = 0;

    final String a = "aafswerg";
    final String b = "assdfsaf";
    final String c = "aasfasfsaf";
    final String d = "afafafdaa";
    final String e = "afdassadf";

    startTime = System.currentTimeMillis();
    concat1(run, a, b, c, d, e);
    total = System.currentTimeMillis() - startTime;
    System.out.println(total);

    startTime = System.currentTimeMillis();
    concat2(run, a, b, c, d, e);
    total = System.currentTimeMillis() - startTime;
    System.out.println(total);

    startTime = System.currentTimeMillis();
    concat3(run, a, b, c, d, e);
    total = System.currentTimeMillis() - startTime;
    System.out.println(total);
}

private static void concat3(int run, String a, String b, String c, String d, String e) {
    for (int i = 0; i < run; i++) {
        String str = new StringBuilder(a.length() + b.length() + c.length() + d.length() + e.length()).append(a)
                .append(b).append(c).append(d).append(e).toString();
    }
}

private static void concat2(int run, String a, String b, String c, String d, String e) {
    for (int i = 0; i < run; i++) {
        String str = new StringBuilder(a).append(b).append(c).append(d).append(e).toString();
    }
}

private static void concat1(int run, String a, String b, String c, String d, String e) {
    for (int i = 0; i < run; i++) {
        String str = a + b + c + d + e;
    }
}
}

这个程序实际演示了哪种方法最快,并且可以在运行时进行测试。请告诉我为什么会有负评。 - leoismyname

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接