たこぜりー研究室

大腸菌DNAは4.64Mbp。酵母は13Mbpで、ヒトは3Gbp

スポンサーサイト

#
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

EqualityComparer.Default でリニアサーチ

#519
長さ 10 万の整数列を 1000 回リニアサーチ。
static void Main(string[] args)
{
  Stopwatch sw = new Stopwatch();
  int[] array = Enumerable.Range(1, 100000).ToArray();

  sw.Start();
  for (int i = 0; i < 1000; i++)
    One(array, 90000);
  sw.Stop();
  Console.WriteLine(sw.Elapsed);
  sw.Reset();

  sw.Start();
  for (int i = 0; i < 1000; i++)
    Two(array, 90000);
  sw.Stop();
  Console.WriteLine(sw.Elapsed);
  sw.Reset();

  sw.Start();
  for (int i = 0; i < 1000; i++)
    One(array, 90000);
  sw.Stop();
  Console.WriteLine(sw.Elapsed);
  sw.Reset();
}

static int One(int[] array, int value)
{
  for (int i = 0; i < array.Length; i++)
  {
    if (EqualityComparer<int>.Default.Equals(array[i], value))
      return i;
  }
  return -1;
}

static int Two(int[] array, int value)
{
  var comparer = EqualityComparer<int>.Default;

  for (int i = 0; i < array.Length; i++)
  {
    if (comparer.Equals(array[i], value))
      return i;
  }
  return -1;
}

もちろん実際には Array.IndexOf を使えばいいわけだが。

EqualityComparer.Default をループ中に呼び出すのか、呼び出さないのか、の違いをみたいなぁ、という話。

結果 (Release ビルドでデバッグなし実行、.NET 3.5 / Core2 Duo 2.00GHz) :
00:00:01.3417418
00:00:00.5312608
00:00:01.3143324

ループ内呼び出しオワタ

犯人↓
call class [mscorlib]System.Collections.Generic.EqualityComparer`1<!0> [mscorlib]System.Collections.Generic.EqualityComparer`1<int32>::get_Default()

が ldloc.0 になるだけでこの速度差 orz
ここは逆に考えるんだ。1 億回 の呼び出しでようやく 0.8 秒の差なんだと。

コメント


コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURL:  http://takojelly.blog2.fc2.com/tb.php/519-08ec8e76
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。