Open1

Assert.AreEqual は実はとても遅い

Agate PrisAgate Pris

表題の通り。Assert.AreEqual (恐らくその他の同様のメソッドも同様) はとても遅い。

Rust のコードを C# にポートして、同様のテストを記述したところ、300 倍以上の時間がかかったため「C# そこまで遅いのか?そんなわけないよな?」と半ば絶望しつつボトルネックを調査していた課程で気づいた。

以下のようなテストは実効速度に数百倍の差がでることがある。[1]

// Rust
for x in 0..=u32::MAX {
    anyhow::ensure!(f(x) == g(x));
}
// C#
for (var x = 0u; x <= uint.MaxValue; ++x) {
    Assert.AreEqual(F(x), G(x));
}

以下のようにすると良い。[2]

for (var x = 0u; x <= uint.MaxValue; ++x) {
    var fx = F(x);
    var gx = G(x);
    if (fx != gx) {
        // 絶対失敗
        Assert.AreEqual(fx, gx);
    }
}
脚注
  1. ここまで広範囲をテストする場合は実際にはマルチスレッド化した方が良いだろう。 ↩︎

  2. Object.Equals と比較演算子の違いについてはここでは考慮しない。 ↩︎