【问题标题】:Java fastest way to concatenate strings, integers and floatsJava 连接字符串、整数和浮点数的最快方法
【发布时间】:2012-04-19 18:16:26
【问题描述】:

从字符串、整数和浮点数构建字符串的最高效方法是什么?目前我正在这样做,它使用了大量的 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) +
    ";";

有没有办法更快地做到这一点?

【问题讨论】:

标签: java string-concatenation


【解决方案1】:

这应该已经很快了——它会在内部使用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 查看编译器生成了什么...

【讨论】:

  • 这也是我的想法——虽然我不清楚在什么情况下会发生这种情况。是不是当你在循环中使用 + 运算符时编译器不会转换?
  • 你可以用你知道的足够的容量来初始化构建器(但是这么短的字符串不会有太多好处)。还有你为什么需要这个,日志记录?
  • @zolex:你真的需要在每一帧上都这样做吗?真的吗?这是为了谁的利益?
  • @JavaKungFu:不一定是循环。当你使用字符串连接表达式的结果时,基本上 - 所以如果你这样做 String foo = x + ","; foo = foo + z; foo = foo + ","; 将是浪费。
  • @zolex:哎呀,你使用默认编码调用getBytes()。请不要那样做。如果您真的需要字符串表示,请改用OutputStreamWriter。但是为什么不用DataOutputStream 只写你想记录的二进制数据呢?无需字符串转换。
【解决方案2】:

使用StringBuilder

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

【讨论】:

  • 出于兴趣,您为什么认为这样做会更快?
【解决方案3】:

您可以尝试使用StringBuilder

(但是,大多数值得一提的 Java 编译器会自动优化您列出的代码以在幕后使用 StringBuilder。)

【讨论】:

    【解决方案4】:

    如果你想让它运行得非常快,你可以试试我的库,它允许你在微秒内记录消息而不会产生任何垃圾。 https://github.com/peter-lawrey/Java-Chronicle

    (正如我所说,它可能超出你想要的)

    【讨论】:

      【解决方案5】:

      以下 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;
          }
      }
      }
      

      【讨论】:

      • 这个程序在实践中显示哪种方法最快。并且可以在运行时进行测试。请让我知道为什么投反对票。
      猜你喜欢
      • 2021-07-09
      • 1970-01-01
      • 2012-02-04
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 2022-11-22
      • 2015-07-18
      • 2014-03-19
      相关资源
      最近更新 更多