Вопрос: Является ли утверждение goto медленным в c #?


Я работаю над приложением C # .NET, которое использует некоторые довольно сложные научные формулы для больших наборов данных (в среднем 10 миллионов точек данных). Часть того, что я делаю, требует оптимальной оптимизации реализации формул.

Я заметил, что в одной реализации формулы используется goto, и это заставило меня задуматься: медленнее, чем другие конструкции управления потоком?


8


источник


Ответы:


медленнее, чем другие конструкции управления потоком?

Нет. Все другие конструкции управления потоком в основном goto так или иначе.


11



goto инструкция на C # не медленнее любой другой конструкции потока управления. На самом деле подавляющее большинство конструкций управляющего потока (если, в то время как, для и т. Д.) Реализовано в терминах goto,

Например:

if (someExpr) { 
  Console.WriteLine("here");
}
Console.WriteLine("there");

По существу сводится к следующему

gotoIf !someExpr theLabel;
Console.WriteLine("here");
theLabel:
Console.WriteLine("there");

4



Я заметил, что в одной реализации формулы используется goto, и это сделало меня   wonder: 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
            }
        }
    }
}

Есть разные способы вы могли вырваться из всего. Вот один из способов.

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 флаг. Мы могли бы реорганизовать это с помощью 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:

4



ifс и for переведены на gotos внутренне компилятором, чтобы они были не быстрее, чем gotos


1