Большой Воронежский Форум
» Программирование>Инкременты
LSL 15:10 23.01.2004
Как то уважаемый is посоветывал использовать префиксный
инкремент:

лучше использовать его, чем постфиксный. Т.е. в циклах вместо y++
записать ++y.


Решил проверить чем же лучше, и для двух процедур:
Код:
static void Postfix()
{
       for(int i = 0; i < 10; i++)
       {
               Console.WriteLine(i);
       }
}

static void Prefix()
{
       for(int i = 0; i < 10; ++i)
       {
               Console.WriteLine(i);
       }
}
Дизассемблировал, получил одинаковый IL-код :
Код:
.method private hidebysig static void  Prefix() cil managed
{
  .maxstack  2
  .locals init (int32 V_0)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  br.s       IL_000e
  IL_0004:  ldloc.0
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  add
  IL_000d:  stloc.0
  IL_000e:  ldloc.0
  IL_000f:  ldc.i4.s   10
  IL_0011:  blt.s      IL_0004
  IL_0013:  ret
}
Так что разницы нет. Это ещё раз доказывает что "старые" трюки и
ухищрения не подходят для нового языка.

Может быть различие инкриментов проявляется в другом случае ? Кстати
где про это можно почитать в сети ?

LSL добавил [date]1074864980[/date]:
PS:
Для полноты картины ещё и одинаковый код времени выполнения:
Код:
0000000f  jmp         00000018 
00000011  call        dword ptr ds:[79C29078h] // Вызывается метод.
00000017  inc         esi  
00000018  cmp         esi,0Ah 
0000001b  jl          00000011
[Ответ]
antey 16:44 23.01.2004

Сообщение от :
Первоначальное сообщение от LSL
[B]Как то уважаемый is посоветывал использовать префиксный
инкремент:

лучше использовать его, чем постфиксный. Т.е. в циклах вместо y++
записать ++y.

"Привыкнешь и жизнь твоя не будет стоить ломаного цента"...
В таких простых случаях без разницы как использовать. А вот когда надо будет получить результат выражения...

Сообщение от :
Может быть различие инкриментов проявляется в другом случае ?

int i=0;
int j=++i;
i=0;
int k=i++;
if (j != k)
{
throw ("Тады ой!");
}

Неужто не знал?
[Ответ]
LSL 17:02 23.01.2004
antey Это всё понятно.

В таких простых случаях без разницы как использовать.

В том-то и дело что совет был дан к этому случаю. Я именно про цикл. [Ответ]
RomanPshenichny 17:42 23.01.2004
Совет очень даже верен для итераторов. [Ответ]
LSL 19:46 23.01.2004
RomanPshenichny этот совет оказался бессмысленным для моего случая, когда я использовал итератор в цикле, дизассемблированный код оказался одинаков и для префиксной и для постфиксной записи.

Я хочу понять это особенность Си шарпа или у меня частный случай, когда нет разницы. [Ответ]
antey 12:38 24.01.2004

Сообщение от :
Первоначальное сообщение от LSL
этот совет оказался бессмысленным для моего случая, когда я использовал итератор в цикле, дизассемблированный код оказался одинаков и для префиксной и для постфиксной записи.

Я хочу понять это особенность Си шарпа или у меня частный случай, когда нет разницы.

Код:
class X 
{
  private:
     void some_action(){};

  public:
     operator ++()  // префикс
        {
           some_action();
           return *this;
        }

     operator ++(int) // постфикс
        {
           X temp=*this;
           some_action();
           return temp;
        }
};
Найди отличия.
И если ты немного подумаешь, то сможешь понять, что в диезе будет то же самое.
При этом учти, что компилятор всё это наверняка соптимизирует... [Ответ]
is 13:41 24.01.2004
Ух ты, тут вовсю обсуждение моих советов идет, а я и не в курсе :)

LSL Вот смотри как это дело в отношении префиксной и постфиксной форме обстоит в стандарте С++

========================================
[expr.post.incr] 5.2.6 Increment and decrement
1 The value obtained by applying a postfix ++ is the value that the operand had before applying the operator.
[Note: the value obtained is a copy of the original value ] The operand shall be a modifiable lvalue. The
type of the operand shall be an arithmetic type or a pointer to a complete object type. After the result is
noted, the value of the object is modified by adding 1 to it, unless the object is of type bool, in which case
it is set to true. [Note: this use is deprecated, see annex D. ] The result is an rvalue. The type of the
result is the cvunqualified
version of the type of the operand. See also 5.7 and 5.17.


__________________


[expr.pre.incr] 5.3.2 Increment and decrement
1 The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated).
The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer
to a completelydefined
object type. The value is the new value of the operand; it is an lvalue. If x is not
of type bool, the expression ++x is equivalent to x+=1. [Note: see the discussions of addition (5.7) and
assignment operators (5.17) for information on conversions. ]
============================================

Я там вторые подпункты относительно декремента. В них говорится, что в случае декремента аналогично :)

Идем далее :)

Реализация постфиксного инкремента обычно менее эффективно, чем префиксного.
Постфиксный инкремент может выглядеть так

const T T::operator++(int)
{
T tmp(*this);
++*this;
return tmp;
}

Либо для более четкого понимания:

для префиксной формы
y =++x;
аналогично y=(x+=1);
Значением y будет новое значение.

Для постфиксной формы:
y=x++;
аналогично y=(t=x,x+=1,t).
[Прим. is - запятая в С++ устанавливает точки следования]
Значением y будет старое значение x

Так вот к чему я веду? ;) Если старое значение не нужно (насколько я понял в твоём случае это именно так), то использование префиксной формы более предпочтительно.

Т.е. just keep in mind :) Но это для плюсов, для шарпа, возможно, дело обстоит иначе - пока еще до него руки не дошли :( [Ответ]
LSL 14:27 25.01.2004
is Для шарпа так же.
Postfix

1)x is evaluated to produce the variable.
2)The value of x is saved.
3)The selected operator is invoked with the saved value of x as its argument.
4)The value returned by the operator is stored in the location given by the evaluation of x.
5)The saved value of x becomes the result of the operation.

Prefix

1)x is evaluated to produce the variable.
2)The selected operator is invoked with the value of x as its argument.
3)The value returned by the operator is stored in the location given by the evaluation of x.
4)The value returned by the operator becomes the result of the operation.

И всё же, в цикле нет разницы какой инкремент использовать.. [Ответ]
is 17:50 25.01.2004
LSL Да, посмотрел в C# Language Specification.
Но я бы сказал нет разницы в данном случае. На этом предлагаю дискуссию завершить [Ответ]
Grossmeister 17:40 11.02.2004
Постфиксный инкремент отличается от префиксного тем, что возвращает не инкрементированное значение, а исходное.
Правило эффективного использования инкрементов формулируется просто: если вам не нужно исходное значение после увеличения, используйте префиксную форму оператора. Бессмысленное использование постфисной формы приводит к непроизвольному созданию временных объектов, которые порою могут быть очень большими.
В случае, описанном LSL имеет место инкремент встроенного типа int. Для таких простых типов (int, complex, char и пр.) компилятор оказывается способным оптимизировать код благодоря замене постфиксной формы на префиксную.
Так что не стоит строить особенных иллюзий на счет C#, этот язык не слишком отличается от C++, хотя и является менее мощным но более объектно-ориентированным. [Ответ]
LSL 20:23 11.02.2004
Grossmeister

О всевидящие, за что мне такое наказание

Я же привёл пример и на ассемблере и на "независимом языке"! Что может быть ещё очивиднее ?

Факт: в C# в цикле нет разницы какой инкримент использовать. (Возможно у меня частный случай.)

Неужели, я в который раз так недоступно объясняю ?


По поводу сходства с си:

Классы и структуры в c# принципиально отличаются от объектов и структур в Си++.

Обьект в си шарпе это структура данных которая хранится в управляемой куче (managed heap)

Структура - тип данных который хранится в стеке потока домена. Структура является размерным типом, объект - ссылочный.

И вообще это тонкий и серъёзный вопрос, над которым рассуждать не вижу смысла.

Если не ошибаюсь структура и класс в Си++ одно и то же, различие в области видимости..........
[Ответ]
Grossmeister 19:12 12.02.2004
LSL Ты читал что я написал? Для таких простых типов (int, complex, char и пр.) компилятор оказывается способным оптимизировать код благодоря замене постфиксной формы на префиксную. Попробуй инкрементировать итератор.

Grossmeister добавил [date]1076606285[/date]:
И C# в смысле автоматического управления памятью (подобно Java) пока сомнительно (по эффективности) себя ведет. [Ответ]
LSL 23:08 12.02.2004
Grossmeister

Ты читал что я написал?

Это я к тому твоему выссказыванию: "C#, этот язык не слишком отличается от C++"

Для таких простых типов (int, complex, char и пр.) компилятор оказывается способным оптимизировать код благодоря замене постфиксной формы на префиксную

Скорее всего.

Попробуй инкрементировать итератор.

А я что делал ?

И C# в смысле автоматического управления памятью (подобно Java) пока сомнительно (по эффективности) себя ведет.

В чём же сомнения если не сектрет? [Ответ]
Grossmeister 23:20 12.02.2004
LSL

Сообщение от :
В чём же сомнения если не сектрет?

Боюсь что в некоторых случаях (например, резкое наращивание и урезание контейнерных объектов) будет сильно тормозить БД на нем точно писать не будут, разве что простенькие клиентские приложения (мультиплатформенную клиентскую логику).

Сообщение от :
Попробуй инкрементировать итератор.

А я что делал ?

Ты увеличивал тип int.
[Ответ]
LSL 00:42 13.02.2004
Grossmeister
Боюсь что в некоторых случаях (например, резкое наращивание и урезание контейнерных объектов) будет сильно тормозить

Что такое контейнерные объекты ? Я с большой увереностью заявляю что при создании и уничтожении объектов никаких тормозов нет и не будет.

на нем точно писать не будут, разве что простенькие клиентские приложения (мультиплатформенную клиентскую логику).

.net, ado.net - отличный выбор для бд. Это факт.

Только что играл в Quake 2 переписанный под .net, www.vertigosoftware.com. Одним слово - круто Так что ты там говорил про тормоза ? [Ответ]
Вверх