我正在研究與化學公式密切相關的科學研究軟件。我使用內部的Dictionary<Isotope, int>
跟蹤化學式的內容,其中Isotope
是「碳-13」,「氮-14」之類的對象,並且int
代表化學式中這些同位素的數量。所以公式C2H3NO會存在這樣的:當試圖更新一個類型的字典時,防止雙重哈希操作Dictionary <IComparable,int>
{"C12", 2
"H1", 3
"N14", 1
"O16", 1}
這是所有罰款和花花公子,但是當我要添加兩種化學公式放在一起,我最終不得不計算Isotope
哈希函數兩次更新值,請參閱後續代碼示例。
public class ChemicalFormula {
internal Dictionary<Isotope, int> _isotopes = new Dictionary<Isotope, int>();
public void Add(Isotope isotope, int count)
{
if (count != 0)
{
int curValue = 0;
if (_isotopes.TryGetValue(isotope, out curValue))
{
int newValue = curValue + count;
if (newValue == 0)
{
_isotopes.Remove(isotope);
}
else
{
_isotopes[isotope] = newValue;
}
}
else
{
_isotopes.Add(isotope, count);
}
_isDirty = true;
}
}
}
雖然這可能看起來不是這將是一個緩慢的下降,它是當我們增加十億化學式一起,這種方法是一致的程序(>的運行時間的45%的最慢的部分)。我正在處理像「H5921C3759N1023O1201S21」這樣的大型化學公式,這些化學公式一直通過較小的化學公式加入。
我的問題是,是否有更好的數據結構來存儲這樣的數據?我試圖創建一個簡單的IsotopeCount
對象,其中包含一個int
,所以我可以訪問引用類型(而不是值類型)中的值以避免雙重散列函數。但是,這似乎並不有利。
編輯 Isotope
是不可變的,程序的生命週期內應該不會改變,所以我應該能夠緩存的哈希碼。
我已經鏈接到source code,所以你可以看到更深入的類,而不是我複製和粘貼在這裏。
我同意你和@jonskeet關於緩存「同位素」的哈希碼,這對性能有一點幫助。但我認爲減速是詞典的內部因素,我正在尋找避免重複調用訪問內存中相同位置的方法。 – Moop 2012-07-30 21:02:55
如果您針對性能進行優化(並且不關心內存使用情況),則可以爲每個同位素分配一個唯一的'int'索引,該索引將用作'int'數組索引。你將在每一個公式中使用更多的內存,但是數組訪問會更快。 – 2012-07-30 21:09:06
這是一個有趣的想法。正如其他用戶所指出的那樣,我將重點關注一些我會一直使用的「同位素」(即C,N,H,O,S,P),並且可以爲這些獨特的'int '值(即0 - 20)。所有其他同位素我可以分配一個更大的獨特'int',如果用戶添加了一個不尋常的元素,例如'Hf',我只需調整內部的int []'數組來調整它。這應該可以節省內存並提高性能。 – Moop 2012-07-31 18:37:42