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比較的文章)。