我注意到当我从单个帖子中调用new String(byte[])
时,它的速度非常快。但是当我从几个不同的线程中调用它时,它变得非常缓慢。
例如,我有一个调用new String(bytes)
的解析器。如果我按顺序调用解析器50次,每个解析大约需要100ms,但如果我创建50个线程并调用解析,则每个解析需要12000ms到21000ms! (它在后来的线程中变慢)。似乎String(bytes)结构被定义为同步。
探查器跟踪了new String(bytes)
的瓶颈,实际上当我将其更改为new String("Hello")
时,解析器在多线程中变得和在单线程中一样快。
有谁知道为什么会这样?什么是解决方法?
更新
我的验证测试是错误的,因为显然Java编译器有一些内部优化,它们共享String对象,而不是在我调用new String("Hello")
时创建新对象。这就是为什么我做出改变时速度更快的原因。我将重写我的测试代码,并将更新此问题。
答案: 下面的@nafas和@peter答案都是正确的。字符串本身并不慢,但是分析器错误地将它们识别为瓶颈。真正的罪魁祸首是:
答案 0 :(得分:2)
如果RAM很低,则JVM与操作系统交换到HDD。增加可用性Xmx和Xms以获得更好的性能。
答案 1 :(得分:2)
我很确定,它不是String class
,因为它们是immutable
,它们与同步或线程无关。
如果核心数量相对较低(例如2)并且你制作了50个线程,则会降低速度相当大的因素。因为你在程序中创造了额外的复杂性。
每次你的CPU循环通过线程花费一些时间,
选择我通常使用的线程数没有经验法则:
number of Cores + 1
注意:强>
如果你说了很多API调用我会选择更多线程,而如果线程纯粹使用CPU(因为你正在使用它们),那么我会选择较少数量的线程(threads= #cores + 1
)