簡體   English   中英

為什么 Queue.poll 比 Iteration 快? (java.util.concurrent.ConcurrentLinkedQueue)

[英]Why is Queue.poll faster than Iteration? (java.util.concurrent.ConcurrentLinkedQueue)

我有一段代碼可以從隊列中獲取所有元素。 之后我不關心隊列的狀態,我可以保證在我從隊列中刪除元素時隊列不會被修改。

我最初使用迭代器來拉取元素,因為我認為它比輪詢元素更快......

但我進行了以下測試:

ConcurrentLinkedQueue<Object> queue = new ConcurrentLinkedQueue<>();
for (int i=0; i < 1000000; i++)
    queue.add(new Object());

LinkedList<Object> list = new LinkedList<>();
long start = System.currentTimeMillis();
for (Object object: queue)
    list.add(object);
long time1 = System.currentTimeMillis() - start;

list = new LinkedList<>(); 
start = System.currentTimeMillis();
Object object;
while ((object = queue.poll()) != null)
    list.add(object);
long time2 = System.currentTimeMillis() - start;

System.out.println(time1 + " " + time2);

我得到以下輸出(平均超過 100 次運行)

1169 46

我的問題是:為什么輪詢比迭代快? 這對我來說完全不直觀,因為 poll 必須修改隊列,而 iterate 只需要查看狀態。

編輯---格雷是對的

我在循環中運行它並得到輸出(首先應該這樣做)

1180 46
1422 25
287 32
14 26
226 26
236 25
12 26
14 25
13 25
13 26
13 25
268 25
13 25
14 176
13 26
13 26
13 25
13 25
13 26
13 24
13 26
13 25
...

我的問題是:為什么輪詢比迭代快? 這對我來說完全不直觀,因為 poll 必須修改隊列,而 iterate 只需要查看狀態。

正如@csoroiu 指出的那樣,這似乎是一個熱點編譯器問題。 鑒於 Java 的工作原理,在開始執行這樣的計時調用之前“預熱”應用程序非常重要。

如果我在一個方法中運行您的測試 100 次,由於 GC 開銷和其他 JVM 魔法,我最初看到的性能有很大不同。 但是,在方法.clear()添加一些.clear()方法和System.gc()后,性能數字與迭代器獲勝更加一致:

108 143
89 152
83 148
78 140
79 153
90 155
...

有關更多詳細信息,請參閱 Peter 在此處的回答: Java 中的 CPU 執行時間

有關如何正確執行此類微基准測試的更多信息,請參閱此詳盡答案: 如何在 Java 中編寫正確的微基准測試?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM