更新:嘿家伙感谢回复.昨晚和今晚我尝试了几种不同的方法,并提出了类似于Jeff下面列出的方法(我甚至已经完成了他在更新中建议的内容,并将我自己的简单LL实现放在一起以获得额外收益).这是代码,此时它看起来并不特别干净,但是我已经多次改变了我可以做的任何事情以增强性能.
public class NewLRU2where V : class { int m_iMaxItems; Dictionary > m_oMainDict; private LRUNode m_oHead; private LRUNode m_oTail; private LRUNode m_oCurrent; public NewLRU2(int iSize) { m_iMaxItems = iSize; m_oMainDict = new Dictionary >(); m_oHead = null; m_oTail = null; } public V this[K key] { get { m_oCurrent = m_oMainDict[key]; if (m_oCurrent == m_oHead) { //do nothing } else if (m_oCurrent == m_oTail) { m_oTail = m_oCurrent.Next; m_oTail.Prev = null; m_oHead.Next = m_oCurrent; m_oCurrent.Prev = m_oHead; m_oCurrent.Next = null; m_oHead = m_oCurrent; } else { m_oCurrent.Prev.Next = m_oCurrent.Next; m_oCurrent.Next.Prev = m_oCurrent.Prev; m_oHead.Next = m_oCurrent; m_oCurrent.Prev = m_oHead; m_oCurrent.Next = null; m_oHead = m_oCurrent; } return m_oCurrent.Value; } } public void Add(K key, V value) { if (m_oMainDict.Count >= m_iMaxItems) { //remove old m_oMainDict.Remove(m_oTail.Key); //reuse old LRUNode oNewNode = m_oTail; oNewNode.Key = key; oNewNode.Value = value; m_oTail = m_oTail.Next; m_oTail.Prev = null; //add new m_oHead.Next = oNewNode; oNewNode.Prev = m_oHead; oNewNode.Next = null; m_oHead = oNewNode; m_oMainDict.Add(key, oNewNode); } else { LRUNode oNewNode = new LRUNode (key, value); if (m_oHead == null) { m_oHead = oNewNode; m_oTail = oNewNode; } else { m_oHead.Next = oNewNode; oNewNode.Prev = m_oHead; m_oHead = oNewNode; } m_oMainDict.Add(key, oNewNode); } } public bool Contains(K key) { return m_oMainDict.ContainsKey(key); } } internal class LRUNode { public LRUNode(K key, V val) { Key = key; Value = val; } public K Key; public V Value; public LRUNode Next; public LRUNode Prev; }
有一些部分看起来/感觉不稳定 - 比如在进行添加时重用旧节点 - 但我能够从中获得明显的性能提升.我对从节点上的实际属性切换到公共变量所产生的差异也略感惊讶,但我想这就是它与这些东西的关系.在这一点上,上面的代码几乎完全受到字典操作的性能限制,所以我不确定我是否可以通过混搭来获得更多.我将继续思考并研究一些回应.
来自原帖的解释:大家好.所以我编写了一个简单的轻量级LRU实现用于压缩库(我用它来根据散列,LZW样式在输入中查找匹配的字节串),我正在寻找制作方法它更快.