LFU C# 實現

週六早上  作了下力扣的LRU 題目  後面接着看了LFU 緩存  難度提升了很多node

首先 先說下 這2着 的差異把算法

LRU :最近 最少使用算法(Least  Recently Used).LRU 是淘汰最長時間沒有被使用的頁面。緩存

LFU:最不常常使用淘汰算法(Least Frequently Used)LFU 是淘汰 一段時間內,使用次數最少的頁面。spa

看到這些  感受都差很少  不是很明白 下面舉個實例說明下問題code

假設內存塊大小是3:blog

咱們所需頁面順序 也就是緩存讀取頁面的順序是 以下:內存

1  2   1  2  1  3   4ci

當咱們去獲取頁面4的時候   內存塊裏面 存是應該 是  1  2  3  這個時候 就會發生缺頁中斷 ,並且內存已經滿了  須要策略去替換頁面leetcode

若是咱們採用的是LRU 算法  應該替換掉的是2     由於  2 是最長時間 沒被訪問的  1,3 在4以前別訪問  因此要替換2資源

可是 若是採用LFU 算法  那替換的就是3   由於  在 4被訪問以前  這段時間內    1訪問3次   2是2次   3是1次  因此要替換 3    若是存在訪問次數相同低的  刪除 最久的節點   

再次舉例下  1  2   1  2  1  3   3   4   若是是這樣的順序     1是3次    2是 2次  3 頁是2次      可是2訪問順序在3以前   也就是呆的久   因此替換  2節點

LRU  消耗CPU 資源少   LFU 消耗CPU 資源高   本身實現下 就知道這2個的難易程度了。

好了 說了這麼多  下面show code:

 public class LFUCache2
    {
        private Dictionary<int, LFUCacheEntity> dicData; //KeyValuePair 
        public Dictionary<int, LinkedList<LFUCacheEntity>> dicFrequenNodeList;// key 是頻率    value是key頻率下面 所掛的node 數據節點
        private int _capacity;//容量大小
        private int minFre;//頻率值

        public LFUCache2(int capacity)
        {
            _capacity = capacity;
            dicData = new Dictionary<int, LFUCacheEntity>(capacity);
            dicFrequenNodeList = new Dictionary<int, LinkedList<LFUCacheEntity>>();
            minFre = 0;
            dicFrequenNodeList.Add(0, new LinkedList<LFUCacheEntity>());
        }

        public int Get(int key)
        {
            if (!dicData.ContainsKey(key))
                return -1;
            var value = dicData[key].Value;
            Put(key, value);
            return value;
        }

        public void Put(int key, int value)
        {
            if (_capacity == 0)
                return;

            var newCacheData = new LFUCacheEntity { Key = key, Value = value, Frequen = 0 };
            if (dicData.ContainsKey(key))
            {
                var cacheEntity = dicData[key];

                var oldFrequen = cacheEntity.Frequen;
                var oldFrequenNodeList = dicFrequenNodeList[oldFrequen];
                oldFrequenNodeList.Remove(cacheEntity);

                var newFrequen = oldFrequen + 1;
                if (!dicFrequenNodeList.ContainsKey(newFrequen))
                {
                    dicFrequenNodeList.Add(newFrequen, new LinkedList<LFUCacheEntity>());
                }
                newCacheData.Frequen = newFrequen;
                dicFrequenNodeList[newFrequen].AddLast(newCacheData);
                dicData[key] = newCacheData;
                if (dicFrequenNodeList.ContainsKey(minFre) && dicFrequenNodeList[minFre].Count == 0)
                {
                    minFre = newFrequen;
                }
                return;
            }

            if (_capacity == dicData.Count)
            {
                var deleteNodeList = dicFrequenNodeList[minFre];
                var deleteFirstNode = deleteNodeList.First;
                deleteNodeList.RemoveFirst();
                dicData.Remove(deleteFirstNode.Value.Key);
            }
            dicFrequenNodeList[0].AddLast(newCacheData);
            dicData.Add(key, newCacheData);
            minFre = 0;
        }
    }

    public class LFUCacheEntity
    {
        public int Key { get; set; }
        public int Value { get; set; }
        public int Frequen { get; set; }
    }

 

最後貼下 題目地址:https://leetcode-cn.com/problems/lfu-cache/

在貼下 執行的代碼狀況:

 

 可是很奇怪的是:LFUCacheEntity  這個若是設置稱類  耗時特別的塊三百多毫秒   若是設置成結構就是近600毫秒  上面是我執行的結果狀況

明天去研究下 

相關文章
相關標籤/搜索