簡體   English   中英

為什么我的基於模數的緩沖區比寫的LinkedList慢?

[英]Why is my modulus-based buffer slower than a LinkedList for writing?

背景:

我試圖找到最快的(關於寫入速度)鍵值存儲來支持我擁有的應用程序。 存儲的最大容量為15,000個鍵值對。 我嘗試了以下方法:

  • LinkedHashMap ,重寫removeEldestEntry可以在地圖中的項目數達到15000時刪除最舊的條目:

     new LinkedHashMap<Long, Object>(10000, 0.75F, false) { private static final long serialVersionUID = 1L; protected boolean removeEldestEntry(Map.Entry<Long, Object> eldest) { return size() > 15000; } }; 
  • LinkedList ,如果大小已經達到最大值,則刪除第一個元素(要獲取具有鍵id元素,將按順序搜索列表):

     new LinkedList<Object>() { private static final long serialVersionUID = 1L; public boolean add(Object o) { while (size() >= 15000) remove(0); return super.add(o); } }; 
  • 我可以想到的ModBuffer ,這是我能想到的(理論上)最快的存儲(如列表中,找到具有鍵id元素,整個緩沖區將按順序搜索):

     public class ModBuffer<T> { private T[] buffer = (T[]) new Object[15000]; public add(Long key, T value) { int pos = (int) (key % (long) buffer.length); buffer[pos] = value; } 

直觀地看,ModBuffer似乎是編寫速度最快的一種。 但是事實證明,LinkedList是最快的。 我正在使用這些緩沖區來實現網絡協議。 有了LinkedList,我設法達到850Mbps。 使用ModBuffer,它不會超過700Mbps。

題:

為什么LinkedList的編寫速度比簡單的ModBuffer快得多? 由於它是標准Java Collections的一部分,它是否以某種方式進行了優化? 我想不出任何其他原因了……這很有趣。

我懷疑是模運算符比添加到鏈表中要慢。 ModBuffer實現中,始終執行模數。 另一方面, LinkedList實現調用一個O(1) size方法,然后調用另一個O(1) add方法插入列表的開頭。 如果條目數不超過15k的最大值,則可以通過while條件中的分支預測來增加一項改進:

while (size() >= 15000)
     remove(0);

如果您要在循環中添加元素並且條目數未達到最大值,則大多數情況下將返回false。

但是,對於大量條目,情況並非如此-模數緩沖區應該更有效。

聽起來您在談論協議的速度,而不是高速緩存的寫入速度。 如果協議中有重傳部分,那么較低的速度可能是由於ModBuffer奇怪且可能很差的保留特性引起的。 當基於LinkedList的解決方案丟棄隊列中最舊的記錄時,ModBuffer解決方案有效地丟棄隨機記錄; 每當發生緩存沖突時,它都會丟棄記錄。 可能需要重新傳輸這些丟失的記錄,這使您放慢了速度。

暫無
暫無

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

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