Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > размер вектора в цикле


Автор: mrgloom 21.6.2011, 11:00

оптимизируется ли компилятором код
Код

for (int i=0;i<vec.size();++i)
{}


или надо 
Код

int size= vec.size();
for (int i=0;i<size;++i)
{}



Автор: triclosan 21.6.2011, 11:09
вектор "знает" о своем размере, vec.size() не считает а всего лишь возвращает значение поєтому накладные расходы не большие, а читаемость кода лучше.

Добавлено через 1 минуту и 37 секунд
Цитата(mrgloom @  21.6.2011,  11:00 Найти цитируемый пост)
оптимизируется ли компилятором код

Такое навряд ли оптимизируется компилятором, откуда компилятору знать, что надумает вернуть метод класса 

Автор: borisbn 21.6.2011, 11:15
mrgloom, если вектор (вернее его размер) в цикле изменяется, то стОит делать i < vec.size(). В противном же случае - как нравится. Я, например, завожу переменную (типа size у тебя). Так проще отлаживаться - остановился на breakpoint'е и смотришь эту переменную...

Цитата(triclosan @  21.6.2011,  11:09 Найти цитируемый пост)
а читаемость кода лучше

на вкус и цвет...


Автор: asmdzen 21.6.2011, 11:19
triclosan, вот что я нашел в stl_vector.h
Код

      /**  Returns the number of elements in the %vector.  */
      size_type
      size() const
      { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }


если размер достаточно большой - получится довольно много вычислений. обычно когда не имеет значения я прохожу контейнеры в обратном направлении, типа 
Код

for (int i=vec.size() - 1;i>=0;--i)
{}

Автор: mrgloom 21.6.2011, 11:28
Цитата(asmdzen @  21.6.2011,  11:19 Найти цитируемый пост)
обычно когда не имеет значения я прохожу контейнеры в обратном направлении
for (int i=vec.size() - 1;i>=0;--i)


не понял смысл

Автор: asmdzen 21.6.2011, 11:40
Код

size_type size() const
        {    // return length of sequence
        return (_Mysize);
        }


это уже просто vector.h, поскольку функция написана прямо в классе то я думаю получится прямое обращение к переменной _Mysize класса vector, значит оптимизация есть.
Цитата(mrgloom @  21.6.2011,  11:28 Найти цитируемый пост)
не понял смысл 

что именно не понятно? если использовать 
Код

for (int i=vec.size() - 1;i>=0;--i)

то метод size() будет вызван только один раз.

Автор: azesmcar 21.6.2011, 12:37
Цитата(mrgloom @  21.6.2011,  11:00 Найти цитируемый пост)
оптимизируется ли компилятором код

это надо смотреть на конкретно компиляторе, но писать так все равно не стоит.
для итерации по вектору существуют итераторы.

Автор: borisbn 21.6.2011, 12:42
Цитата(azesmcar @  21.6.2011,  12:37 Найти цитируемый пост)
для итерации по вектору существуют итераторы

ээээххххх, опоздал я. хотел то же самое сказать.
ну, тогда, просто +1 за итераторы smile

Автор: boostcoder 21.6.2011, 14:04
на gcc-4.5.2, этот код:
Код

int main(int argc, char * argv[])
{
   int s = rand()%10;
   printf("%d\n", s);
   std::vector<int> v(s);
   
   for(int idx = 0; idx < v.size(); ++idx) {
      printf("idx: %d", idx);
   }
}


генерируется в такой ассемблер:
Код

004013B0 loc_4013B0:
004013B0 mov     [esp+20h+var_1C], ebx // аргумент для printf`a
004013B4 mov     [esp+20h+var_20], offset aIdxD ; "idx: %d" // форматная строка
004013BB call    printf
004013C0 inc     ebx // инкремент
004013C1 cmp     esi, ebx // сравнение
004013C3 ja      short loc_4013B0 // повторяем

в esi лежит размер.
как не сложно заметить, vector::size() в цикле не вызывается.

Автор: borisbn 21.6.2011, 14:16
Цитата(boostcoder @  21.6.2011,  14:04 Найти цитируемый пост)
как не сложно заметить, vector::size() в цикле не вызывается.

хммм. а если в цикл вставить
Код
v.pop_back();

?

Автор: boostcoder 21.6.2011, 14:17
скажу даже больше: как показывает практика, gcc компиляторы в условии цикла не вызывают функцию/метод, а вызывают ее/его один раз при инициализации.

Добавлено через 25 секунд
Цитата(borisbn @  21.6.2011,  14:16 Найти цитируемый пост)
а если в цикл вставить

чичас smile

Автор: fish9370 21.6.2011, 14:25
хочу лишь добавить, что такая функция (функция, которая не изменяет своего значения при вызовах с одним и тем же агрументом) называется чистой (pure) и разумеется компилятор впервую очередь выносит ее за цикл..

у gcc есть расширение, которое позволяет принудительно объявить функцию чистой, на случай если вы не доверяете компилятору.. 

Автор: boostcoder 21.6.2011, 14:29
а тут все еще интересней smile
код:
Код

int main(int argc, char * argv[])
{
   int s = rand()%10;
   printf("%d\n", s);
   std::vector<int> v(s);
   
   for(int idx = 0; idx < v.size(); ++idx) {
      v.pop_back();
      printf("idx: %d", idx);
   }
}



получилось такое:
Код

004013B0 loc_4013B0:
004013B0 sub     esi, 4
004013B3 mov     [esp+20h+var_1C], ebx
004013B7 mov     [esp+20h+var_20], offset aIdxD ; "idx: %d"
004013BE call    printf
004013C3 inc     ebx
004013C4 mov     eax, esi
004013C6 sub     eax, edi
004013C8 sar     eax, 2
004013CB cmp     eax, ebx
004013CD ja      short loc_4013B0

в esi размер.
ebx - индекс.


ну, выскажите свое мнение относительно плохого оптимизатора smile

Добавлено через 2 минуты и 5 секунд
Цитата(fish9370 @  21.6.2011,  14:25 Найти цитируемый пост)
называется чистой (pure)

вот:
Код

      // [23.2.4.2] capacity
      /**  Returns the number of elements in the %vector.  */
      size_type
      size() const
      { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }



Добавлено через 3 минуты и 47 секунд
ааа, она уже есть выше)
и никакого pure.

Автор: fish9370 21.6.2011, 14:48
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

Код

pure
Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. 
Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. 
These functions should be declared with the attribute pure. For example,
          int square (int) __attribute__ ((pure));

Автор: boostcoder 21.6.2011, 14:50
fish9370, я в курсе.
я вам показал, что никакого pure у метода size() нет.

Автор: fish9370 21.6.2011, 14:53
Цитата(boostcoder @  21.6.2011,  14:50 Найти цитируемый пост)
я вам показал, что никакого pure у метода size() нет.


повторяю, его нет потому-что компилятор ее (функцию) и так определяет как чистую.. это ответ на вопрос топикстартера..

Автор: bsa 21.6.2011, 15:07
fish9370, твоя цитата к классам не относится.

Автор: fish9370 21.6.2011, 15:07
Цитата(bsa @  21.6.2011,  15:07 Найти цитируемый пост)
к классам это не относится.


это относится ко всему..

Автор: boostcoder 21.6.2011, 15:19
Цитата(fish9370 @  21.6.2011,  14:53 Найти цитируемый пост)
компилятор ее (функцию) и так определяет как чистую

к чему тогда приведена цитата?
а на основании чего компилятор принимает решение о том что она чистая?
и как он может это сделать, если к примеру, он видит только декларацию(не в этом примере)?

Автор: fish9370 21.6.2011, 15:22
Цитата(bsa @  21.6.2011,  15:07 Найти цитируемый пост)
твоя цитата к классам не относится


ну, это применять я никого не обязываю, это было приведено в позновательных целях.. суть от этого не меняется..

PS, может я вам кайф обламал, а вы хотели еще погадать на ассемблерной гуще? - тогда я прошу прощения.. а вообще бы плюсонуть не помешало бы.. 

Автор: asmdzen 21.6.2011, 15:28
Цитата(asmdzen @  21.6.2011,  11:40 Найти цитируемый пост)
size_type size() const
        {    // return length of sequence
        return (_Mysize);
        }


это уже просто vector.h, 


непонятно почему две разные версии, но может из-за того что функции inline и получается оптимизация с регистрами?

boostcoder, я так понимаю после цикла значение esi все же сохраняется в переменную vector'а?

Автор: boostcoder 21.6.2011, 15:39
Цитата(asmdzen @  21.6.2011,  15:28 Найти цитируемый пост)
непонятно почему две разные версии

из какой версии STL этот код?

Автор: asmdzen 21.6.2011, 15:40
boostcoder, той что идет с VC 2008

Автор: boostcoder 21.6.2011, 15:41
asmdzen, а разве тогда еще использовались расширения файлов у STL ? по моему нет...

Автор: triclosan 21.6.2011, 15:49
Цитата(asmdzen @  21.6.2011,  15:28 Найти цитируемый пост)
size_type size() const
        {    // return length of sequence
        return (_Mysize);
        }

для sdt::vector<bool>

Автор: borisbn 21.6.2011, 16:20
Цитата(boostcoder @  21.6.2011,  14:29 Найти цитируемый пост)
sub     esi, 4

фигасе... это v.pop_back() ???  smile 
+10050 тогда gcc smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)