私はそれが古い質問であることを知っていますが、経験的なデータを少し追加するだけです...
10,000 エントリの辞書で 50,000,000 回のルックアップを実行し、完了するまでの相対時間を比較します。
..すべてのルックアップが成功した場合:
- まっすぐな (チェックされていない) 実行には 1.2 秒かかります
- 保護された (ContainsKey) 実行には 2 秒かかります
- 処理された (try-catch) 実行には 1.21 秒かかります
..10,000回のルックアップごとに1回失敗した場合:
- 保護された (ContainsKey) 実行には 2 秒かかります
- 処理された (try-catch) 実行には 1.37 秒かかります
..10,000 回のルックアップのうち 16 回が失敗した場合:
- 保護された (ContainsKey) 実行には 2 秒かかります
- 処理された (try-catch) 実行には 3.27 秒かかります
..10,000 回のルックアップのうち 250 回が失敗した場合:
- 保護された (ContainsKey) 実行には 2 秒かかります
- 処理された (try-catch) 実行には 32 秒かかります
..したがって、保護されたテストは一定のオーバーヘッドを追加しますが、それ以上のことはありません.try-catch テストは、失敗しない場合はテストなしとほぼ同じ速度で動作しますが、失敗の数に比例してパフォーマンスが低下します。
テストの実行に使用したコード:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{ Test(0);
Test(1);
Test(16);
Test(250);
}
private static void Test(int failsPerSet)
{ Dictionary<int, bool> items = new Dictionary<int,bool>();
for(int i = 0; i < 10000; i++)
if(i >= failsPerSet)
items[i] = true;
if(failsPerSet == 0)
RawLookup(items, failsPerSet);
GuardedLookup(items, failsPerSet);
CaughtLookup(items, failsPerSet);
}
private static void RawLookup
( Dictionary<int, bool> items
, int failsPerSet
){ int found = 0;
DateTime start ;
Console.Write("Raw (");
Console.Write(failsPerSet);
Console.Write("): ");
start = DateTime.Now;
for(int i = 0; i < 50000000; i++)
{ int pick = i % 10000;
if(items[pick])
found++;
}
Console.WriteLine(DateTime.Now - start);
}
private static void GuardedLookup
( Dictionary<int, bool> items
, int failsPerSet
){ int found = 0;
DateTime start ;
Console.Write("Guarded (");
Console.Write(failsPerSet);
Console.Write("): ");
start = DateTime.Now;
for(int i = 0; i < 50000000; i++)
{ int pick = i % 10000;
if(items.ContainsKey(pick))
if(items[pick])
found++;
}
Console.WriteLine(DateTime.Now - start);
}
private static void CaughtLookup
( Dictionary<int, bool> items
, int failsPerSet
){ int found = 0;
DateTime start ;
Console.Write("Caught (");
Console.Write(failsPerSet);
Console.Write("): ");
start = DateTime.Now;
for(int i = 0; i < 50000000; i++)
{ int pick = i % 10000;
try
{ if(items[pick])
found++;
}
catch
{
}
}
Console.WriteLine(DateTime.Now - start);
}
}
}