Java Thread到底有多快/慢?
创建一个能占满CPU的任务,然后启动CPU个,看时间,然后启动更多,看平均每个任务的执行时间。
计算Fibonacci数列的算法。
启动n个线程,每个线程计算一个fib数列,看总的时间。
单位计算资源占用效率的计算:CPU占用×时间/计算的数量
10000fib |
|
|
|
系统5% |
|
线程数 |
|
|
cpu |
纯CPU |
单位效率 |
1 |
171 |
ms |
35% |
30.00% |
51.30 |
2 |
181 |
ms |
40% |
35.00% |
31.68 |
3 |
195 |
ms |
45% |
40.00% |
26.00 |
4 |
210 |
ms |
45% |
40.00% |
21.00 |
6 |
320 |
ms |
50% |
45.00% |
24.00 |
8 |
366 |
ms |
55% |
50.00% |
22.88 |
12 |
540 |
ms |
70% |
65.00% |
29.25 |
16 |
756 |
ms |
80% |
75.00% |
35.44 |
32 |
1409 |
ms |
100% |
95.00% |
41.83 |
48 |
1826 |
ms |
100% |
95.00% |
36.14 |
64 |
2505 |
ms |
100% |
95.00% |
37.18 |
128 |
5540 |
ms |
100% |
95.00% |
41.12 |
192 |
8351 |
ms |
100% |
95.00% |
41.32 |
256 |
10900 |
ms |
100% |
95.00% |
40.45 |
512 |
20484 |
ms |
100% |
95.00% |
38.01 |
512 |
21766 |
ms |
100% |
95.00% |
40.39 |
512 |
22634 |
ms |
100% |
95.00% |
42.00 |
1024 |
44248 |
ms |
100% |
95.00% |
41.05 |
2048 |
77111 |
ms |
100% |
95.00% |
35.77 |
2732 |
104636 |
ms |
100% |
95.00% |
36.39 |
分析:随着线程数从1到4的增加,单位线程的消耗减少,说明线程初始化等的消耗随着线程数的增加,平摊下来,单位性能在上升,随着后面的逐渐升高,现场的效率在下降,但是有一个现象不好解释,就是如果是因为线程的切换导致了单位性能的下降,那么为什么后面随着线程数的提高,基本上逐渐稳定了?初步分析,由于只计算了10000的Fib数,单个计算时间太少,171ms左右,所以很快的就执行完了,则系统的统计不准确。所以计算一个多的看效果。
50000fib |
|
|
|
系统5% |
|
线程数 |
|
|
cpu |
纯CPU |
单位效率 |
1 |
4200 |
ms |
33% |
27.00% |
1134.00 |
2 |
4585 |
ms |
56% |
50.00% |
1146.25 |
3 |
4855 |
ms |
80% |
74.00% |
1197.57 |
4 |
5200 |
ms |
100% |
94.00% |
1222.00 |
6 |
7836 |
ms |
100% |
94.00% |
1227.64 |
8 |
10425 |
ms |
100% |
94.00% |
1224.94 |
12 |
15740 |
ms |
100% |
94.00% |
1232.97 |
16 |
20161 |
ms |
100% |
94.00% |
1184.46 |
32 |
41134 |
ms |
100% |
94.00% |
1208.31 |
64 |
81775 |
ms |
100% |
94.00% |
1201.07 |
128 |
164025 |
ms |
100% |
94.00% |
1204.56 |
512 |
656164 |
ms |
100% |
94.00% |
1204.68 |
这次的情况是:随着线程数量的增加,基本上不会有太大的单位计算效率的波动。
结论:2-3k个线程内,基本上系统的切换损耗很少(估计是一次切换,CPU密集的应用会运行相当长的一段时间,所以相对于CPU密集型的计算,则线程切换的损耗就可以忽略不计了,通常切换在us级别,而一次切换后,线程的运行在50ms级别,但是如果程序IO处理自身本身很快的要切换,需要另当别论。)
但是,如果是非CPU密集型的计算,那么线程对Latency有影响吗?切换有影响,但不是Java特别的(需考究)。
另外,java版本和C版本,对CPU密集型的计算,效率差异有多大?不大(后面有个针对C和Java比较的文章)。