私は化学式を多用する科学研究用のソフトウェアに取り組んでいます。「炭素13」、「窒素14」などのオブジェクトDictionary<Isotope, int>
である内部を使用して化学式の内容を追跡します。これは、化学式内のそれらの同位体の数を表します。したがって、式C2H3NOは次のように存在します。Isotope
int
{"C12", 2
"H1", 3
"N14", 1
"O16", 1}
これはすべて問題なくダンディですが、2つの化学式を一緒に追加したい場合Isotope
、値を更新するために2回のハッシュ関数を計算する必要があります。次のコード例を参照してください。
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
しかし、これは有益ではなかったようです。
EDIT
Isotope
は不変であり、プログラムの存続期間中は変更されないため、ハッシュコードをキャッシュできるはずです。
私はソースコードにリンクしているので、ここにコピーして貼り付けるのではなく、クラスをより深く見ることができます。