注:私は過去の経験とプロファイラソフトウェアのアドバイスのために最適化しています。代替の最適化は、GetNeighbors
をあまり頻繁に呼び出さないことに気付きましたが、現時点では二次的な問題です。C#マイクロ最適化クエリ:IEnumerable Replacement
私は以下に説明する非常に単純な機能を持っています。一般に、私はforeachループの中でそれを呼び出します。私はその機能をたくさん(毎秒約10万回)呼びます。しばらく前に、私はJavaでこのプログラムのバリエーションをコーディングしていましたが、速度をあまりにもうんざりさせ、いくつかのforループを4つのif文で置き換えました。ループアンローリングは醜いと思われますが、アプリケーションの速度に顕著な差がありました。だから、私はいくつかの潜在的な最適化を思い付くと、私は自分のメリットにと提案について意見を求めるだろうと思ってきました:
- 十字完全文とはDRY原則を無視した場合。私はこれが過去の経験に基づいてパフォーマンスを改善すると確信していますが、それは私を悲しくします。明確にするために、4つのif文をgetNeighbors()をあまりにも頻繁に呼び出す場所にペーストし、foreachブロックの内側をペーストします。
- いくつかの不思議な方法で結果をメモしてください。
- すべての四角に「近隣」プロパティを追加します。初期化時にその内容を生成します。
コード生成ユーティリティを使用して、GetNeighborsの呼び出しをコンパイルの一部としてif文に変換します。
public static IEnumerable<Square> GetNeighbors(Model m, Square s) { int x = s.X; int y = s.Y; if (x > 0) yield return m[x - 1, y]; if (y > 0) yield return m[x, y - 1]; if (x < m.Width - 1) yield return m[x + 1, y]; if (y < m.Height - 1) yield return m[x, y + 1]; yield break; } //The property of Model used to get elements. private Square[,] grid; //... public Square this[int x, int y] { get { return grid[x, y]; } }
注:GetNeighbors関数で費やされた時間の20%はm.get_Itemへの呼び出しに費やされ、他の80%は方法自体に費やされています。
最適化が必要であるときには(この場合はDRYで)あなたの原則を放棄しても大丈夫です。それについては気にしないでください。将来の開発者があなたの最適化をリファクターしないように文書化してください。 –