現在、ゲームにサウンド エフェクトを追加する作業を行っています。現在のコードは問題なく動作していますが、簡素化する方法を探しています。基本的に、ゲーム内の各オブジェクトには、その材質 (「木」、「金属」など) を示す文字列値があり、2 つのオブジェクトが衝突すると、その組み合わせに基づいてサウンド エフェクトが再生されます。コードは基本的に次のようになります。
if( (matA == "metal" && matB == "wood") || (matA == "wood" && matB == "metal") )
{
//play sound for metal-wood collision
}
しかし、if ステートメントを次のように簡略化する方法があるかどうか疑問に思っています。
if( one of the materials is wood && one of the materials is metal )
{
//play sound for metal-wood collision
}
ベストアンサー1
enum
マテリアルには文字列の代わりにを使用し、Dictionary
対応するサウンドの組み合わせを保持するには を使用します。if
を使用すると、複数のステートメントをスキップし、各マテリアルに対応するオブジェクトを自動的に選択できますDictionary
。例:
[Flags]
enum Material
{
Wood=1,
Iron=2,
Glass=4
//...
}
Dictionary<Material,SoundObject> sounds = new Dictionary<Material,SoundObject>();
sounds.add(Material.Wood,woodSound);
sounds.add(Material.Iron,ironSound);
sounds.add(Material.Wood | Material.Iron,woodAndIronSound);
// And play corresponding sound directly without any if statement.
sounds[object.Material].Play();
sounds[matA | matB].Play();
パフォーマンス上の利点:
このアプローチを使用すると、パフォーマンスも向上します。なぜなら、Enum 値またはハッシュ コードの整数比較は、文字列比較よりも間違いなく簡単で高速だからです。また、辞書と複数のif-else
ステートメントについては、一連のif/else if
ステートメントは線形に実行されるため、そのパフォーマンスは、if ステートメントの数とオブジェクトの等価比較子に大きく依存します。一方、Dictionary
Hashtable に基づいています。インデックス最適化コレクションを使用して値を格納し、実質的にアクセス時間が一定になります。つまり、辞書にキーがいくつあっても、一定時間で値にアクセスでき、ほとんどのシナリオでは、複数の if ステートメントよりも非常に高速です。
パフォーマンス比較:
この例では、2 つのアプローチのパフォーマンスを比較します。
//If you want to try, just copy the code and see the result.
static Dictionary<char, short> myHashTable = Enumerable.Range((short)'A', (short)'z').ToDictionary((ch) => (char)ch, (sh) => (short)sh);
static void Main(string[] args)
{
System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
short temp = 0;
SW.Start();
for(int i=0;i<10000000;i++)
temp = getValue('z');
SW.Stop();
Console.WriteLine(SW.ElapsedMilliseconds );
SW.Reset();
SW.Start();
for(int i =0;i<10000000;i++)
temp = myHashTable['a'];
SW.Stop();
Console.WriteLine(SW.ElapsedMilliseconds);
}
static short getValue(char input)
{
if (input == 'a')
return (short)'a';
else if (input == 'b')
return (short)'b';
else if (input == 'c')
return (short)'c';
else if (input == 'd')
return (short)'d';
else if (input == 'e')
return (short)'e';
else if (input == 'f')
return (short)'f';
else if (input == 'g')
return (short)'g';
else if (input == 'h')
return (short)'h';
else if (input == 'i')
return (short)'i';
else if (input == 'j')
return (short)'j';
else if (input == 'k')
return (short)'k';
else if (input == 'l')
return (short)'l';
else if (input == 'm')
return (short)'m';
else if (input == 'n')
return (short)'n';
else if (input == 'o')
return (short)'o';
else if (input == 'p')
return (short)'p';
else if (input == 'q')
return (short)'q';
else if (input == 'r')
return (short)'r';
else if (input == 's')
return (short)'s';
else if (input == 't')
return (short)'t';
else if (input == 'u')
return (short)'u';
else if (input == 'v')
return (short)'v';
else if (input == 'w')
return (short)'w';
else if (input == 'x')
return (short)'x';
else if (input == 'y')
return (short)'y';
else if (input == 'z')
return (short)'z';
return 0;
}
結果:
if
26項目の文| 122項目の辞書。
593 254
579 256
572 252
570 246
587 248
574 291
576 246
685 265
599 282
723 338
これは、辞書がステートメントよりも 2 倍以上高速であることを示していますif/else if
。