回想起第一種做法,我們使用最原始的方式,使用字典來儲存物件,不過我們需要拼接出乙個龐大的字串,因為它具有「唯一性」。但是其實從那時開始,我們就已經走了一條彎路。在.net framework中,乙個物件如果要作為字典的「鍵」,難道一定要是字串嗎?很顯然,答案是否定的。事實上,任何型別的物件都可以作為字典的鍵,而字典認為兩個「鍵」物件相同依靠的是物件的gethashcode方法和equals方法。字典的整個查詢分兩步走:
首先根據gethashcode獲取物件雜湊值,用於確定需要查詢的物件在那個分組(或者說是「桶」,在資料結構中稱為雜湊表的「buckets」)中。
每個分組的物件數量很少,然後在使用equals方法依次進行比較,最終得到相同的那個值。
因為有了expressioncomparer和expressionhasher,我們已經可以非常輕鬆地實現那個作為「鍵」的物件了:
private classcachekey
public cachekey(expression exp)
private int m_hashcode;
private bool m_hashcodeinitialized = false;
public override int gethashcode()
return this.m_hashcode;
}public override bool equals(object obj)
}
最後再實現乙個dictionarycache:
public classdictionarycache
: iexpressioncache
where t : class
}finally
this.m_rwlock.enterwritelock();
tryvalue = creator(key);
this.m_storage.add(cachekey, value);
return value;
}finally
}}
dictionarycache的實現其實和hashedlistcache比較接近,不過從理論上說,dictionarycache的效能不如hashedlistcache。因為同樣在根據雜湊值獲取到分組後,dictionarycache中的分組元素數量可能會比hashedlistcache要多(因為字典中多個雜湊值也可以在同乙個分組中);同時,字典在同組的k個元素中找到指定元素使用o(k)的遍歷演算法,而二叉搜尋樹只要o(log(k))的時間複雜度——此消彼長,dictionarycache的效能自然就要略差一些了。)。
談表示式樹的快取(5) 引入雜湊值
到目前為止,我們已經實現了三種快取方式 首先我們設法構建唯一字串,但是由於它的代價較高,於是我們使用了字首樹進行儲存 又由於字首樹在實際操作中所花的時間和空間都有不令人滿意之處,我們又引入了二叉搜尋樹。那麼二叉搜尋樹又有什麼缺點呢?其實前文已經談到過了,那就是從理論上來說,它的時間複雜度相對前兩個要...
談表示式樹的快取(5) 引入雜湊值 1
到目前為止,我們已經實現了三種快取方式 首先我們設法構建唯一字串 但是由於它的代價較高,於是我們使用了字首樹 進行儲存 又由於字首樹在實際操作中所花的時間和空間都有不令人滿意之處,我們又引入了二叉搜尋樹 那麼二叉搜尋樹又有什麼缺點呢?其實前文已經談到過了,那就是從理論上來說,它的時間複雜度相對前兩個...
談表示式樹的快取(1) 引言
表示式樹 expression tree 是.net 3.5中引入的一種表達方式。表示式樹的運用十分廣泛,可以直觀地表現出各種 資料 甚至 邏輯 和 行為 再者,表示式樹是強型別的,因此合理地使用這個新特性可以讓 編寫變得優雅,方便。乙個最簡單而常見的例子便是,某些朋友目前就已經喜歡使用表示式樹來代...