为什么在stringbuilder的构造函数中使用concateration要比调用append()快100倍?

1mrurvl1  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(319)

我偶然发现了一个与 StringBuilderappend 方法。我注意到在使用 StringBuilder 构造函数(这甚至在netbeanside中显示为警告)。
版本1

int hash = -1;     //lazily computed, also present in Version 2
int blockID = ...  //0 to 1000, also present in Version 2
int threadID = ... //0 to 1000, also present in Version 2
boolean hashed = false;       //also present in Version 2

@Override
public int hashCode(){
    if(!hashed){
        StringBuilder s = new StringBuilder(blockID+":"+threadID);
        hash = s.toString().hashCode();
        hashed= true;
    }

    return hash;
}

数以百万计的这些对象是在运行时创建的,因此我认为通过进行以下更改,它将提供一些加速:
版本2

@Override
public int hashCode(){
    if(!hashed){
        StringBuilder s = new StringBuilder(blockID);
        s.append(":");
        s.append(threadID);
        hash = s.toString().hashCode();
        hashed = true;
    }

    return hash;
}

错了!实际上,版本2比版本1慢100倍。为什么?
附加信息
我是根据Java6(客户需求)编译的,我使用的是oracle的jvm。
我的性能测试包括创建一百万个这样的对象并将它们放入hashmap中。使用版本1需要半秒钟,但使用版本2需要将近50秒钟。

eyh26e7m

eyh26e7m1#

因为您无意中设置了 StringBuilder 而不是附加 blockID 去吧。请参阅此处的构造函数文档。
公共stringbuilder(int容量)
构造一个字符串生成器,其中不包含任何字符,并且由capacity参数指定初始容量。
请尝试以下操作:

StringBuilder s = new StringBuilder(9);
s.append(blockID).append(':').append(threadID);
bwitn5fc

bwitn5fc2#

你需要检查你的测试,因为你的第一个案例实际上正在做。

public int hashCode(){
    if(!hashed){
        StringBuilder s = new StringBuilder(
                  new StringBuilder(blockID).append(":").append(threadID).toString());
        hash = s.toString().hashCode();
        hashed= true;
    }

    return hash;
}

换言之,在第二种情况下,它所做的一切都是这样,因此它的速度会更慢。
简言之,我怀疑你的测试是错误的,并不是说你的表现越来越好。

相关问题