Старый 23.01.2004, 15:10   #1   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
Cool Инкременты

Как то уважаемый 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
  Ответить с цитированием
Старый 23.01.2004, 16:44   #2   
парадоксов друг...
 
Аватар для antey
 
Сообщений: 286
Регистрация: 31.08.2003

antey вне форума Не в сети
Re: Инкременты

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

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

Цитата:
Может быть различие инкриментов проявляется в другом случае ?
int i=0;
int j=++i;
i=0;
int k=i++;
if (j != k)
{
throw ("Тады ой!");
}

Неужто не знал?
  Ответить с цитированием
Старый 23.01.2004, 17:02   #3   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
antey Это всё понятно.

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

В том-то и дело что совет был дан к этому случаю. Я именно про цикл.
  Ответить с цитированием
Старый 23.01.2004, 17:42   #4   
Форумец
 
Аватар для RomanPshenichny
 
Сообщений: 334
Регистрация: 14.04.2003
Возраст: 42

RomanPshenichny вне форума Не в сети
Совет очень даже верен для итераторов.
  Ответить с цитированием
Старый 23.01.2004, 19:46   #5   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

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

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

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

Я хочу понять это особенность Си шарпа или у меня частный случай, когда нет разницы.
Код:
class X 
{
  private:
     void some_action(){};

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

     operator ++(int) // постфикс
        {
           X temp=*this;
           some_action();
           return temp;
        }
};
Найди отличия.
И если ты немного подумаешь, то сможешь понять, что в диезе будет то же самое.
При этом учти, что компилятор всё это наверняка соптимизирует...
  Ответить с цитированием
Старый 24.01.2004, 13:41   #7   
Форумец
 
Аватар для is
 
Сообщений: 111
Регистрация: 04.02.2003

is вне форума Не в сети
Ух ты, тут вовсю обсуждение моих советов идет, а я и не в курсе :)

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 :) Но это для плюсов, для шарпа, возможно, дело обстоит иначе - пока еще до него руки не дошли :(
  Ответить с цитированием
Старый 25.01.2004, 14:27   #8   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
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.

И всё же, в цикле нет разницы какой инкремент использовать..
  Ответить с цитированием
Старый 25.01.2004, 17:50   #9   
Форумец
 
Аватар для is
 
Сообщений: 111
Регистрация: 04.02.2003

is вне форума Не в сети
LSL Да, посмотрел в C# Language Specification.
Но я бы сказал нет разницы в данном случае. На этом предлагаю дискуссию завершить
  Ответить с цитированием
Старый 11.02.2004, 17:40   #10   
Gross
 
Аватар для Grossmeister
 
Сообщений: 985
Регистрация: 10.05.2002
Возраст: 40
Записей в дневнике: 7

Grossmeister вне форума Не в сети
Постфиксный инкремент отличается от префиксного тем, что возвращает не инкрементированное значение, а исходное.
Правило эффективного использования инкрементов формулируется просто: если вам не нужно исходное значение после увеличения, используйте префиксную форму оператора. Бессмысленное использование постфисной формы приводит к непроизвольному созданию временных объектов, которые порою могут быть очень большими.
В случае, описанном LSL имеет место инкремент встроенного типа int. Для таких простых типов (int, complex, char и пр.) компилятор оказывается способным оптимизировать код благодоря замене постфиксной формы на префиксную.
Так что не стоит строить особенных иллюзий на счет C#, этот язык не слишком отличается от C++, хотя и является менее мощным но более объектно-ориентированным.
  Ответить с цитированием
Старый 11.02.2004, 20:23   #11   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
Grossmeister

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

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

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

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


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

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

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

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

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

Если не ошибаюсь структура и класс в Си++ одно и то же, различие в области видимости..........
  Ответить с цитированием
Старый 12.02.2004, 19:12   #12   
Gross
 
Аватар для Grossmeister
 
Сообщений: 985
Регистрация: 10.05.2002
Возраст: 40
Записей в дневнике: 7

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

Grossmeister добавил [date]1076606285[/date]:
И C# в смысле автоматического управления памятью (подобно Java) пока сомнительно (по эффективности) себя ведет.
  Ответить с цитированием
Старый 12.02.2004, 23:08   #13   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
Grossmeister

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

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

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

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

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

А я что делал ?

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

В чём же сомнения если не сектрет?
  Ответить с цитированием
Старый 12.02.2004, 23:20   #14   
Gross
 
Аватар для Grossmeister
 
Сообщений: 985
Регистрация: 10.05.2002
Возраст: 40
Записей в дневнике: 7

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

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

А я что делал ?
Ты увеличивал тип int.
  Ответить с цитированием
Старый 13.02.2004, 00:42   #15   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

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

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

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

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

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



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind