我有一个Java 8的多线程Http服务器它每秒接收数千个请求,并且必须创建需要字符串连接的响应。解决这个问题最好(最快)的办法是什么?
我知道在一般情况下,StringBuilder
有比+
操作符更好的性能,我认为StringBuilder将是最好的解决方案,但在这种情况下,我必须为每个请求初始化新的StringBuilder。
此外,在我的问题中,串联总是需要3个字符串-其中两个是final,中间一个是变量。该变量可以从~20个不同元素的集合中获取值。因此,可能连接的字符串的数量等于20 x number_of_different_strings,大约是2000。
是更好地使用StringBuilder或只是连接字符串(数量不会超过2k个不同的字符串),或者也许它更好地存储所有创建的字符串(约2k)在map和请求特定的一个每次?
我知道一般
StringBuilder
的性能要比+
好得多
这并不完全正确。实际上,当您使用+
操作符时,Java编译器会在编译的代码中将其转换为使用StringBuilder
。
问题如下。请看下面的代码:
String[] names = {"Joe", "Susan", "Fred", "Mary"};
String result = "";
for (String name : names) {
result = result + name;
}
每次使用+
操作符时,Java编译器将创建一个StringBuilder
来执行该操作。编译器将上面的内容转换成这样:
for (String name : names) {
StringBuilder sb = new StringBuilder(result);
sb.append(name);
result = sb.toString();
}
注意,这是非常低效的代码。在循环的每次迭代中,都会创建一个新的StringBuilder
对象。字符串result
中包含的数据被复制到StringBuilder
中。然后添加下一个名称,然后将StringBuilder
中的数据复制到分配给result
的新String
中。有许多不必要的复制正在进行。
你可以直接使用StringBuilder
来编写更高效的代码:
StringBuilder sb = new StringBuilder();
for (String name : names) {
sb.append(name);
}
String result = sb.toString();
这样,只创建一个StringBuilder
对象,并且在循环的每次迭代中不会将数据复制到它和String
中。
如果您的代码不涉及在循环中附加许多字符串,并且您只需要连接三个字符串,那么无论您显式使用+
还是StringBuilder
都无关紧要。事实上,使用+
编写的代码将被编译成与手动使用StringBuilder
时编写的代码完全相同。