私は、大規模なデータセット(平均で1,000万データポイント)に対してかなり複雑な科学式を使用するC#.NETアプリケーションに取り組んでいます。私がしていることの一部は、数式の実装を可能な限り最適化することを必要とします。
ある数式の実装でgotoが使用されていることに気づきました。それで、gotoは他のフロー制御構造よりも遅いのでしょうか。
gotoは他のフロー制御構造よりも遅いですか?
いいえ。他のすべてのフロー制御構造は基本的にgoto
とにかくです。
C#のgoto
命令は、他のどの制御フロー構造よりも遅くはありません。実際、制御フロー構造の大部分(if、while、forなど...)は、の観点から実装されていgoto
ます。
例えば:
if (someExpr) {
Console.WriteLine("here");
}
Console.WriteLine("there");
基本的に次のようにコンパイルされます
gotoIf !someExpr theLabel;
Console.WriteLine("here");
theLabel:
Console.WriteLine("there");
ある数式の実装でgotoが使用されていることに気づきました。それで、gotoは他のフロー制御構造よりも遅いのでしょうか。
goto
他のフロー制御メカニズムよりも遅くなることはありません。ほとんどのフロー制御メカニズムと同様に、br.s
(または同様の)MSIL命令にコンパイルされます。ただし、goto
少し速くなる場合があります。それらは主に、ネストされたループの使用break
とその内部を含む状況に限定されます。continue
次のコードを検討してください。
bool condition = false;
for (int i = 0; i < BigNumber; i++)
{
for (int j = 0; j < i; j++)
{
for (int k = 0; k < j; k++)
{
condition = Evaluate(i, j, k);
if (condition)
{
// break out of everything
}
}
}
}
あなたが全体から抜け出すことができるさまざまな方法があります。これが1つの方法です。
bool condition = false;
for (int i = 0; i < BigNumber; i++)
{
for (int j = 0; j < i; j++)
{
for (int k = 0; k < j; k++)
{
condition = Evaluate(i, j, k);
if (condition) break;
}
if (condition) break;
}
if (condition) break;
}
condition
問題は、各ループがフラグをチェックする必要があることです。これをaでリファクタリングして、goto
起動を少し効率的にし、もう少しエレガントにすることができます。
for (int i = 0; i < BigNumber; i++)
{
for (int j = 0; j < i; j++)
{
for (int k = 0; k < j; k++)
{
if (Evaluate(i, j, k)) goto BAILOUT;
}
}
}
BAILOUT:
if
sおよびはコンパイラによって内部的にsfor
に変換されるため、 sよりも高速ではありませんgoto
goto