我正在开发大量处理化学公式的科学研究软件。我使用内部来跟踪化学式的内容,Dictionary<Isotope, int>
其中Isotope
是“Carbon-13”,“Nitrogen-14”之类的对象,并且int
表示化学式中这些同位素的数量。所以公式 C2H3NO 会像这样存在:
{"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
包含 a 的简单对象,int
这样我就可以访问引用类型(而不是值类型)中的值以避免双重哈希函数。然而,这似乎并没有什么好处。
EDIT
Isotope
是不可变的,在程序的生命周期内不应更改,因此我应该能够缓存哈希码。
我已链接到源代码,因此您可以更深入地查看这些类,而不是我在这里复制和粘贴它们。