2016-01-05 74 views
3

我正在使用JMH對自定義集合實現運行性能測試。JMH中的非對稱基準測試

我想模仿一個場景,其中讀取次數比寫入次數大10倍。

我用this不對稱基準實例和創建一組具有10個讀取器線程和1個寫線程:

@Benchmark 
@BenchmarkMode(Mode.AverageTime) 
@OutputTimeUnit(TimeUnit.MICROSECONDS) 
@Group("g0") 
@GroupThreads(1)  
public void baselinePut0(CacheState0 state) { writing } 

@Benchmark 
@BenchmarkMode(Mode.AverageTime) 
@OutputTimeUnit(TimeUnit.MICROSECONDS) 
@Group("g0") 
@GroupThreads(10) 
public Integer baselineGet0(CacheState0 state) { reading } 

我運行-wi 10 -i 10 -f 1 PARAMS測試。在報告中,變量cnt所有的基準是一樣的:

Benchmark     Mode Cnt  Score  Error Units 
Benchmark.g0    avgt 10 262,537 ? 215,406 us/op 
Benchmark.g0:baselineGet0 avgt 10  2,101 ? 0,154 us/op 
Benchmark.g0:baselinePut0 avgt 10 1252,231 ? 697,807 us/op 

這是不是意味着大量的讀取等於在實驗中寫的是多少?如果是這樣,如何正確實施?更一般的說法是:我在這個設置中錯過了什麼?

+0

除非你真的* *需要獲得獨立的測量爲讀/寫,我寧願用對稱的(隨機)測試拋出去ThreadLocalRandom支持的骰子是否應該讀取或寫入。這樣您就更加仔細地平衡了操作組合,並且不依賴於線程調度。你不能在可以容納11個正在運行的線程的機器上運行,而不會相互踩踏,是嗎? ;) –

回答

1

Cnt顯示樣本數(不是線程數)。你的情況是10,因爲你正在用-i 10運行你的測試。它會更容易看到這個參數不是線程數,如果你與所有運行PARAMS設置爲唯一值(如-i 13,而@GroupThreads(10)保持不變)

你也可以(臨時)輸出行添加到你的測試,看看每個線程來自哪裏,例如對於讀者(以及與單詞「作家」的作家相似):

System.out.println("reader " + Thread.currentThread().getName()); 
+0

這意味着讀取次數爲10次,寫入次數爲10次。你知道如何實現我在一個問題中描述的目標嗎? – AdamSkywalker

+0

Cnt不是讀/寫次數,而是樣本數。您不知道讀取/寫入的次數,因爲Mode.AverageTime會在時間限制內執行儘可能多的操作(http://hg.openjdk.java.net/code-tools/jmh/file/) bcec9a03787f/jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_02_BenchmarkModes.java) 但是再想一想,我發現'Cnt'在你的情況下應該是100,所以你可能忘了提供線程的數量,例如class或'-t 11'上的'@Threads(11)'作爲命令行參數?如果你沒有,測試將總共運行1個線程(我認爲)作爲默認值 –

+1

您正確地獲得10個樣本的任何一個子測試,因爲迭代樣本也是(在「avgt」模式)平均參與線程。因此,在每次迭代中,「put」測試從單個線程獲取樣本,「get」測試獲得10個線程的平均樣本。經過10次迭代,您可以在兩個子測試中得到10個樣本。這與多線程「吞吐量」測試非常相似:每次迭代的樣本是所有線程的總吞吐量。 –