Есть ли разница в производительности с ++ i против i + = 1 в C #? - PullRequest
4 голосов
/ 31 июля 2011

i + = a должно быть эквивалентно i = i + a.В случае, когда a == 1, это, предположительно, менее эффективно, чем ++ i, так как требует большего доступа к памяти;или компилятор сделает это точно так же, как ++ i?

Ответы [ 5 ]

12 голосов
/ 31 июля 2011

Легко ответить: компилятор C # переводит исходный код C # в коды операций IL. Нет специального кода операции IL, который выполняет эквивалент оператора ++. Что легко увидеть, если вы посмотрите на сгенерированный IL с помощью инструмента ildasm.exe. Этот образец C # фрагмент:

        int ix = 0;
        ix++;
        ix = ix + 1;

Формирует:

  IL_0000:  ldc.i4.0               // load 0
  IL_0001:  stloc.0                // ix = 0

  IL_0002:  ldloc.0                // load ix
  IL_0003:  ldc.i4.1               // load 1
  IL_0004:  add                    // ix + 1
  IL_0005:  stloc.0                // ix = ix + 1

  IL_0006:  ldloc.0                // load ix
  IL_0007:  ldc.i4.1               // load 1
  IL_0008:  add                    // ix + 1
  IL_0009:  stloc.0                // ix = ix + 1

Генерирует точно такой же код . Ничто не может сделать джиттер, кроме как генерировать машинный код, который одинаково быстр.

Оператор приращения до / после - это синтаксический сахар в C #, используйте его везде, где он делает ваш код более разборчивым. Или, возможно, более уместно: избегайте этого там, где это делает менее разборчивым. Они умеют создавать выражения, которые имеют слишком много побочных эффектов.

4 голосов
/ 31 июля 2011

Компилятор должен оптимизировать код в зависимости от того, как вы его пишете, поэтому я считаю, что i = i + 1 совпадает с ++ i.

2 голосов
/ 31 июля 2011

Не думаю, что будет какая-то разница, но Вы можете привести это в действие, что-то вроде:

class Program
{
    static void Main(string[] args)
    {
        //Add values
        List<objClass> lst1 = new List<objClass>();
        for (int i = 0; i < 9000000; i++)
        {
            lst1.Add(new objClass("1", ""));
        }

        //For loop ++i
        DateTime startTime = DateTime.Now;
        for (int i = 0; i < 9000000; ++i)
        {
            lst1[i]._s1 = lst1[i]._s2;
        }
        Console.WriteLine((DateTime.Now - startTime).ToString());

        //For loop i+=1
        startTime = DateTime.Now;
        for (int i = 0; i < 9000000; i+=1)
        {
            lst1[i]._s1 = lst1[i]._s2;
        }
        Console.WriteLine((DateTime.Now - startTime).ToString());

    }
public class objClass
    {
        public string _s1 { get; set; }
        public string _s2 { get; set; }

        public objClass(string _s1, string _s2)
        {
            this._s1 = _s1;
            this._s2 = _s2;
        }
    }

}
1 голос
/ 31 июля 2011

Это зависит.Теоретически, учитывая достаточно наивный компилятор, ++x вполне может быть более эффективным, чем x += 1.

Однако я не знаю такого наивного компилятора.

  • если значение операнда известно во время компиляции, то компилятор может оптимизировать операцию.
  • если можно определить, что значение является постоянным во время выполнения, то JIT-компилятор также может оптимизировать операцию.

Более того, современные процессоры представляют собой очень сложные звери, которые могут выполнять множество операций параллельно, и довольно часто «простые» операции, подобные этим, могут быть полностью скрыты, если их запускать параллельно с большимиболее сложные.

Хорошее эмпирическое правило, когда вы оптимизируете и просто пишете в целом, должны выражать свои намерения настолько четко, насколько это возможно .

Это делает егодругим программистам легче читать ваш код, но это также облегчает компилятору это.

Если вы хотите увеличить значение, используйте приращениеоператор (++), потому что он точно описывает, что вы хотите сделать.

Если вы хотите добавить переменную или неизвестное значение, используйте оператор +=, потому что именно для этого.

Если вы четко понимаете свои намерения, то компилятор получает больше информации о вашем коде и может оптимизировать его соответствующим образом.

Если вы напишите x += 1, выдействительно пытаюсь сбить с толку компилятор.Вы говорите: «Используйте оператор сложения общего назначения, чтобы добавить один к x».Затем компилятор должен выяснить: «Хорошо, вы сказали , чтобы использовать сложение общего назначения, но я вижу, что в этом нет необходимости, поэтому я просто собираюсь вместо этого увеличивать».Вы могли бы сказать это так.Теперь вместо этого вы должны полагаться на умный компилятор.

0 голосов
/ 31 июля 2011

Если a не определено как const int == 1, как компилятор может узнать во время компиляции, что a == 1?

Таким образом, ответ должен быть отрицательным, компилятор не может скомпилировать это в ++ i.

...