【问题标题】:String initialisation and concatenation in javajava中的字符串初始化和连接
【发布时间】:2023-03-16 21:15:01
【问题描述】:

在我的应用程序中一切正常,但我想提高性能并优化我的代码

这两个哪个更适合

1.初始化

String str1=new String("Hello");
String str2="Hello";

2.串联

System.out.println(s1 + s2);
System.out.println(new StringBuffer(S1).append(s2));

【问题讨论】:

标签: java performance


【解决方案1】:

首先,不要提高性能和优化您的代码,除非您首先分析您的应用程序并意识到这样做的充分理由。

其次,对于 String 变量的初始化,最好不要使用 String 构造函数。使用常量字符串(如 str2 所做的那样),Java 可以将字符串对象从字符串池中拉出。

第三,不要使用 StringBuffer 进行连接。请改用 StringBuilder。 StringBuffer 的方法是同步的,这会显着降低您的应用程序的速度。事实上,你的两种连接几乎是相等的,因为所有现代编译器都创建字节码,它使用 StringBuilder 来表示像“s1 + s2”这样的表达式。

【讨论】:

  • +1 在大多数情况下,最简单的示例要么更快,要么一样快。编写更简单的代码有其自身的好处,例如通常更重要的可维护性,因此请坚持使用更简单、更清晰的代码,除非您已经衡量需要更改某些内容并衡量改进。
【解决方案2】:

对于初始化,第二种方法更好:

String str2="Hello";

因为通过这种方式,您可以利用 Java 字符串池并避免不必要的分配。

对于连接,当您必须执行大量字符串连接时,第二种方法是最好的选择,仅连接两个字符串,第一种方法更简单且足够......

【讨论】:

  • 我想补充一点,StringBuilder 比 StringBuffer 快(它不同步)。
【解决方案3】:

使用

String str2="Hello";

用于字符串初始化,因为如果“Hello”字符串在 JVM 字符串池中可用,则不会创建新的内存对象

另外两个建议:

  1. 如果您正在处理字符串,请使用 StringBuffer,因为它不会像 String 类那样在每次字符串操作时创建新字符串。
  2. 如果您的应用程序是线程安全的,则使用StringBuilder 以避免不必要的 StringBuffer 开销,它是为多线程操作而设计的。

【讨论】:

    【解决方案4】:

    对于初始化,最好使用第二个版本,因为这将启用 JVM 字符串“interned”,这意味着每次使用该常量时它总是可以返回相同的字符串实例。第一个版本在遇到此代码时总是会创建一个新的 String 对象,从而造成额外的内存消耗。

    对于连接,在像您的示例这样的简单情况下,编译器将进行优化,因此两种方式最终将基本相同。对于更复杂的字符串连接,最好使用 Stringbuffer 或 StringBuilder。当从多个线程访问 StringBuilder 时,必须使用 StringBuffer,在其他情况下,StringBuilder 将提供更好的性能,因为它不会进行任何锁定。

    【讨论】:

      【解决方案5】:

      initialization

       String str2="Hello";
      

      更好的方法

      concatenation

      System.out.println(s1 + s2);
      

      是更好的方法。

      因为他们都使用String Constant pool,这是为了提高性能

      【讨论】:

        【解决方案6】:
        System.out.println(s1 + s2);
        System.out.println(new StringBuffer(S1).append(s2));
        
        1. 从以上两个来看,第一个会更快,因为+is translated into StringBuilder, that is faster compared to StringBuffer

        2. 不管怎样...最快,但有些讨厌,添加 2 个字符串的方法是使用 string1.concat(string2) 方法,不需要生成 Buffer 的 Stringbuilder 的新对象。

        3. 您还可以重复使用相同的 StringBuilder 来添加多个字符串,方法是在每个完全添加的字符串后使用 sb.setLength(0) 重置它

        StringBuilder sb = new StringBuilder();
        String done1 = sb.append("1").append("2").append("3").toString();
        sb.setLength(0);
        String done2 = sb.append("4").append("5").append("6").toString();
        sb.setLength(0);
        String done3 = sb.append("7").append("8").append("9").toString();
        sb.setLength(0);
        System.out.println(done1);
        System.out.println(done2);
        System.out.println(done3);
        

        最后,在循环内部,您应该始终明确地使用 StringBuilder/Buffer,忽略使用 + 的魔力。因为你最终会得到许多临时的 StringBuilder 对象,而不是只有一个你应该在循环之前显式创建的对象。

            //not:
            String result = "";
            for (int i = 0; i < 20; i++) {
                result += i; // this would create new StringBuilding in bytecode
            }
            System.out.println(result);
        
            //but:
            StringBuilder result1 = new StringBuilder();
            for (int i = 0; i < 20; i++) {
                result1.append(i);
            }
            System.out.println(result1);
        

        【讨论】:

          【解决方案7】:

          在初始化中第二种方法很好,因为它只创建一个对象

          String str1=new String("Hello");

          这里创建了两个对象,一个在堆中,另一个在字符串池中

          String str2="Hello";

          这里只在字符串池中创建了一个对象。

          System.out.println(s1 + s2);

          这里共有三个对象,s1 s2 和 s1+s2 都在字符串池中

          System.out.println(new StringBuffer(S1).append(s2));

          这里只有一个头部区域的对象 S1+S2 所以在这两种情况下第二种方法都很好

          【讨论】:

            【解决方案8】:

            1)Go for literals,字符串字面量存储在一个公共池中。这有助于为具有相同内容的字符串共享存储空间以节省存储空间。通过new操作符分配的字符串对象存储在堆中,相同内容不共享存储。

            除了

            文字比使用构造函数更易于阅读。

            2) 使用 StringBuilder 而不是 + 以避免创建多个字符串对象。

            对于第二点,有 2 到 3 个追加或 + 没有太大区别。但是当您将 50 个字符串相互追加时,这很重要。

            可能有帮助:

            大多数与内存相关的问题由 java 本身维护/解决。我相信干净易读的代码,除非它显示出重大影响。

            【讨论】:

              【解决方案9】:

              在您真正需要它之前不要进行优化。

              如果在不需要时进行优化,则会降低可读性并浪费时间。字符串初始化会给您带来性能问题的情况很少见。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-10-04
                • 2023-03-29
                • 2011-03-20
                • 1970-01-01
                • 1970-01-01
                • 2017-10-10
                • 1970-01-01
                相关资源
                最近更新 更多