当前位置:  开发笔记 > 编程语言 > 正文

使用+分配单个字符串值的性能成本是多少

如何解决《使用+分配单个字符串值的性能成本是多少》经验,为你挑选了4个好方法。

我经常想知道,在最初为字符串赋值时,是否存在将字符串拆分为多行以提高可读性的性能成本.我知道字符串是不可变的,因此每次都需要创建一个新的字符串.此外,由于今天真正快速的硬件(除非你处于一些恶魔般的循环中),性能成本实际上是无关紧要的.例如:

String newString = "This is a really long long long long long" +
    " long long long long long long long long long long long long " +
    " long long long long long long long long long string for example.";

JVM或.Net的编译器和其他优化如何处理这个问题.它会创建一个字符串吗?或者它会创建1个字符串然后一个新的连接值,然后另一个连接值再次?

这是出于我自己的好奇心.



1> Jon Skeet..:

这可以保证C#规范与在单个文字中创建字符串相同,因为它是一个编译时常量.从C#3规范的第7.18节:

只要表达式满足上面列出的要求,就会在编译时计算表达式.即使表达式是包含非常量构造的较大表达式的子表达式,也是如此.

(有关"上面列出的要求"的详细信息,请参阅规范:)

Java语言规范在3.10.5节底部附近指定它:

由常量表达式计算的字符串(第15.28节)在编译时计算,然后将其视为文字.



2> coobird..:

实际上,在Java中,编译器会将其String转换为常量.

class LongLongString
{
    public LongLongString()
    {
        String newString = "This is a really long long long long long" +
            " long long long long long long long long long long long long " +
            " long long long long long long long long long string for example.";
    }

    public static void main(String[] args)
    {
        new LongLongString();
    }
}

编译成:

Compiled from "LongLongString.java"
class LongLongString extends java.lang.Object{
public LongLongString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   ldc #2; //String This is a really long long long long long long long long long long long long long long long long long  long long long long long long long long long string for example.
   6:   astore_1
   7:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #3; //class LongLongString
   3:   dup
   4:   invokespecial   #4; //Method "":()V
   7:   pop
   8:   return

}

可以看出,第4行加载了一行,而不是String加载了多个实例.

编辑:源文件是使用javac版本1.6.0_06 编译的.看看Java语言规范,第三版(和Jon Skeet的答案中提到的相同部分),我无法找到关于编译器是否应该将多行连接String成单个的任何参考String,所以这种行为可能是编译器实现特定的.



3> Drew Noakes..:

自己测试一下.在C#代码中(等效的Java也可以):

string x = "A" + "B" + "C";
string y = "ABC";

bool same = object.ReferenceEquals(x, y); // true

你会看到结果是true.

顺便说一句,您将看到该字符串也在运行时的字符串池中实现:

bool interned = object.ReferenceEquals(x, string.Intern(x)); // true



4> david a...:

没有性能权衡.编译器的优化会将其合并为单个字符串(至少在Java中).

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有