CẬP NHẬT: Xin cảm ơn các bạn đã trả lời. Đêm qua và tối nay tôi đã thử một vài cách tiếp cận khác nhau và đưa ra một cách tương tự với cách mà Jeff đưa ra dưới đây (tôi thậm chí đã làm những gì anh ta đề xuất trong bản cập nhật của mình, và cùng nhau triển khai thực hiện LL đơn giản để tăng thêm). Đây là đoạn mã, vào thời điểm này nó trông không rõ ràng nữa, nhưng tôi đã trải qua nhiều lần thay đổi bất cứ điều gì tôi có thể để tăng cường hiệu suất.Tôi có thể làm cho bộ nhớ cache .NET LRU đơn giản của mình nhanh hơn bằng cách nào?
public class NewLRU2<K, V> where V : class
{
int m_iMaxItems;
Dictionary<K, LRUNode<K, V>> m_oMainDict;
private LRUNode<K,V> m_oHead;
private LRUNode<K,V> m_oTail;
private LRUNode<K,V> m_oCurrent;
public NewLRU2(int iSize)
{
m_iMaxItems = iSize;
m_oMainDict = new Dictionary<K, LRUNode<K,V>>();
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<K, V> 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<K, V> oNewNode = new LRUNode<K, V>(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<K,V>
{
public LRUNode(K key, V val)
{
Key = key;
Value = val;
}
public K Key;
public V Value;
public LRUNode<K, V> Next;
public LRUNode<K, V> Prev;
}
Có một vài phần trông/cảm thấy giống như sử dụng lại nút cũ khi thực hiện thêm - nhưng tôi có thể nhận được sự gia tăng đáng kể về hiệu suất của chúng. Tôi cũng hơi ngạc nhiên trước sự khác biệt mà nó tạo ra để chuyển từ các thuộc tính thực tế trên nút thành các biến công cộng, nhưng tôi đoán đó là cách nó đi với công cụ này. Tại thời điểm này, mã ở trên gần như hoàn toàn bị giới hạn hiệu năng bởi các hoạt động từ điển, vì vậy tôi không chắc chắn tôi sẽ nhận được nhiều hơn từ việc nghiền nó xung quanh. Tôi sẽ tiếp tục suy nghĩ về nó và xem xét một số câu trả lời.
Giải thích từ bài đăng gốc: Xin chào tất cả. Vì vậy, tôi đã viết một triển khai LRU nhẹ đơn giản để sử dụng trong thư viện nén (tôi đang sử dụng nó để tìm các chuỗi byte phù hợp trong đầu vào dựa trên băm, kiểu LZW) và tôi đang tìm cách lam no nhanh hơn.
Related: http://stackoverflow.com/questions/581119/object-cache-for-c –
David, bạn có thể cho chúng tôi ý tưởng về cách bạn sẽ sử dụng bộ nhớ cache không? Các mẫu truy cập trông như thế nào? Bạn thường thêm vào bao lâu? Bạn nhận được bao nhiêu lần? Bạn có thường xuyên làm "Chứa" không? –