简体   繁体   English

为什么我的基于模数的缓冲区比写的LinkedList慢?

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

Background: 背景:

I'm trying to find the fastest possible (regarding write speed) key-value store to back an application that I have. 我试图找到最快的(关于写入速度)键值存储来支持我拥有的应用程序。 The capacity of the store is maximum 15k key-value pairs. 存储的最大容量为15,000个键值对。 I've tried the following: 我尝试了以下方法:

  • LinkedHashMap , overriding removeEldestEntry to remove the eldest entry when the number of items in the map has reached 15000: 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 , removing the first element if the size is already max (to get element with key id , the list is searched sequentially): 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 , the fastest possible (in theory) store I could think of (as in the list, to find element with key id , the whole buffer is searched sequentially): 我可以想到的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; } 

Intuitively, it seems like the ModBuffer would be the fastest one to write. 直观地看,ModBuffer似乎是编写速度最快的一种。 But it turns out that the LinkedList is the fastest one. 但是事实证明,LinkedList是最快的。 I'm using these buffers to implement a network protocol. 我正在使用这些缓冲区来实现网络协议。 With the LinkedList, I manage to reach 850Mbps. 有了LinkedList,我设法达到850Mbps。 With the ModBuffer, it doesn't go beyond 700Mbps. 使用ModBuffer,它不会超过700Mbps。

Question: 题:

Why is the LinkedList so much faster to write than the simple ModBuffer? 为什么LinkedList的编写速度比简单的ModBuffer快得多? Is it optimized somehow, since it's part of the standard Java Collections? 由于它是标准Java Collections的一部分,它是否以某种方式进行了优化? I can't think of any other reason for that... This is quite intriguing. 我想不出任何其他原因了……这很有趣。

I suspect it's the modulus operator that's slower than adding to the linked list. 我怀疑是模运算符比添加到链表中要慢。 In the ModBuffer implementation, a modulus is always executed. ModBuffer实现中,始终执行模数。 On the other hand, the LinkedList implementation calls a O(1) size method then calls another O(1) add method to insert at the beginning of list. 另一方面, LinkedList实现调用一个O(1) size方法,然后调用另一个O(1) add方法插入列表的开头。 If the number of entries does not exceed the maximum of 15k, you can add to that a improvement due to branch prediction in the while condition: 如果条目数不超过15k的最大值,则可以通过while条件中的分支预测来增加一项改进:

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

which would return false most of the time if you're adding elements in a loop and the number of entries does not reach the maximum. 如果您要在循环中添加元素并且条目数未达到最大值,则大多数情况下将返回false。

For a large number of entries, however, this should not be the case -- the modulus-buffer should be more efficient. 但是,对于大量条目,情况并非如此-模数缓冲区应该更有效。

It sounds like you were talking about the speed of the protocol, not the write speed to your cache. 听起来您在谈论协议的速度,而不是高速缓存的写入速度。 If there is a retransmission portion of your protocol, then perhaps the lower speed is caused by the strange and probably poor retention characteristics of the ModBuffer. 如果协议中有重传部分,那么较低的速度可能是由于ModBuffer奇怪且可能很差的保留特性引起的。 Where as your LinkedList-based solutions discard the oldest records in the queue, your ModBuffer solution effectively discards random records; 当基于LinkedList的解决方案丢弃队列中最旧的记录时,ModBuffer解决方案有效地丢弃随机记录; it discards records whenever there is a cache collision. 每当发生缓存冲突时,它都会丢弃记录。 Perhaps the need to retransmit those lost records is what is slowing you down. 可能需要重新传输这些丢失的记录,这使您放慢了速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM