Насколько оправдан данный вызов в цикле?
От: lfpw_  
Дата: 26.02.07 13:33
Оценка:
Весьма часто в чужом коде встречаю примерно следующее:

for(int i = 0; i < container.GetLength(); i++)
{
...
container[i] = ...
...
}

Не ошибаюсь ли я считая, что такое удобное использование GetLength() вредит производительности? Ведь выражение "i < container.GetLength()" пересчитывается на каждой итерации.

Спасибо.
Re: Насколько оправдан данный вызов в цикле?
От: sux Земля  
Дата: 26.02.07 13:37
Оценка:
Здравствуйте, lfpw_, Вы писали:

_>Весьма часто в чужом коде встречаю примерно следующее:


_>for(int i = 0; i < container.GetLength(); i++)

_>{
_> ...
_> container[i] = ...
_> ...
_>}

_>Не ошибаюсь ли я считая, что такое удобное использование GetLength() вредит производительности? Ведь выражение "i < container.GetLength()" пересчитывается на каждой итерации.


_>Спасибо.



вредит, но зависит от реализации getlength

как вариант:


for (int i = container.getlength(); --i >= 0; )
    container[i] = ...
Re[2]: Насколько оправдан данный вызов в цикле?
От: lfpw_  
Дата: 26.02.07 13:47
Оценка:
Ммм... В самом деле, почему бы не писать так. Спасибо!
Re[3]: Насколько оправдан данный вызов в цикле?
От: Аноним  
Дата: 26.02.07 14:26
Оценка:
Здравствуйте, lfpw_, Вы писали:

_>Ммм... В самом деле, почему бы не писать так. Спасибо!


Можно еще и так

for(int i = 0, e = cont.GetLength(); i < e; ++i)
{
   cont[i] = .....
}
Re[4]: Насколько оправдан данный вызов в цикле?
От: sux Земля  
Дата: 26.02.07 14:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Можно еще и так


А>
А>for(int i = 0, e = cont.GetLength(); i < e; ++i)
А>{
А>   cont[i] = .....
А>}
А>


сравнение с нулем работает быстрее чем сравнение со значением в ячейке памяти

p.s. шутка
Re[4]: Насколько оправдан данный вызов в цикле?
От: Alex Dav Россия  
Дата: 26.02.07 14:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, lfpw_, Вы писали:


_>>Ммм... В самом деле, почему бы не писать так. Спасибо!


А>Можно еще и так


А>
А>for(int i = 0, e = cont.GetLength(); i < e; ++i)
А>{
А>   cont[i] = .....
А>}
А>


а разве компилятор не оптимизирует такой вызов?
Re[3]: Насколько оправдан данный вызов в цикле?
От: Кодт Россия  
Дата: 26.02.07 14:33
Оценка: +2
Здравствуйте, lfpw_, Вы писали:

_>Ммм... В самом деле, почему бы не писать так. Спасибо!


Потому что
1) порядок обхода меняется
2) на беззнаковых типах неработоспособно

Можно ещё писать
for(int i=0, n=container.GetLength(); i!=n; ++i) ...
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[5]: Насколько оправдан данный вызов в цикле?
От: Аноним  
Дата: 26.02.07 14:40
Оценка: +1
sux>сравнение с нулем работает быстрее чем сравнение со значением в ячейке памяти

Ок
Зато мой вариант совсем не заставляет напрягать мозг
Re[5]: Насколько оправдан данный вызов в цикле?
От: sux Земля  
Дата: 26.02.07 14:47
Оценка:
Здравствуйте, Alex Dav, Вы писали:

А>>
А>>for(int i = 0, e = cont.GetLength(); i < e; ++i)
А>>{
А>>   cont[i] = .....
А>>}
А>>


AD>а разве компилятор не оптимизирует такой вызов?


во что?
Re[6]: Насколько оправдан данный вызов в цикле?
От: Alex Dav Россия  
Дата: 26.02.07 14:50
Оценка:
Здравствуйте, sux, Вы писали:

sux>Здравствуйте, Alex Dav, Вы писали:


А>>>
А>>>for(int i = 0, e = cont.GetLength(); i < e; ++i)
А>>>{
А>>>   cont[i] = .....
А>>>}
А>>>


AD>>а разве компилятор не оптимизирует такой вызов?


sux>во что?


в то что и надо — cont.GetLength() вызовется один раз
Re[7]: Насколько оправдан данный вызов в цикле?
От: sux Земля  
Дата: 26.02.07 14:55
Оценка:
Здравствуйте, Alex Dav, Вы писали:

A>>>for(int i = 0, e = cont.GetLength(); i < e; ++i)

А>>>{
А>>> cont[i] = .....
А>>>}
А>>>
AD>в то что и надо — cont.GetLength() вызовется один раз

из оригинала в приведенный выше — нет. вызываться getlength будет на каждой итерации цикла
Re[5]: Насколько оправдан данный вызов в цикле?
От: ДимДимыч Украина http://klug.org.ua
Дата: 26.02.07 15:49
Оценка:
Здравствуйте, sux, Вы писали:

sux>сравнение с нулем работает быстрее чем сравнение со значением в ячейке памяти


На x86 в зависимости от процессора сравнение может работать и быстрее, и так же, и медленнее. А быстрее работает модификация операнда / анализ результата на ноль/знак/etc.

sux>p.s. шутка


В каждой шутке...
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[7]: Насколько оправдан данный вызов в цикле?
От: Аноним  
Дата: 26.02.07 16:26
Оценка:
Здравствуйте, Alex Dav, Вы писали:

AD>Здравствуйте, sux, Вы писали:


sux>>Здравствуйте, Alex Dav, Вы писали:


А>>>>
А>>>>for(int i = 0, e = cont.GetLength(); i < e; ++i)
А>>>>{
А>>>>   cont[i] = .....
А>>>>}
А>>>>


AD>>>а разве компилятор не оптимизирует такой вызов?


sux>>во что?


AD>в то что и надо — cont.GetLength() вызовется один раз


Для этого компилятор должен быть уверен, что кол-во элементов контейнера не меняется в процессе выполнения цикла. Но опять же, это будет compiler-specific и почва для еще одного холи-вара на тему "какой компилер круче"
Re[8]: Насколько оправдан данный вызов в цикле?
От: Pavel Anufrikov Россия  
Дата: 27.02.07 05:07
Оценка:
AD>>>>а разве компилятор не оптимизирует такой вызов?
sux>>>во что?
AD>>в то что и надо — cont.GetLength() вызовется один раз
А>Для этого компилятор должен быть уверен, что кол-во элементов контейнера не меняется в процессе выполнения цикла.

Для начала, афайк, компилятор должен быть уверен, что эта функция возвращает кол-во элементов контейнера...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Насколько оправдан данный вызов в цикле?
От: Alex Dav Россия  
Дата: 27.02.07 06:13
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Для этого компилятор должен быть уверен, что кол-во элементов контейнера не меняется в процессе выполнения цикла. Но опять же, это будет compiler-specific и почва для еще одного холи-вара на тему "какой компилер круче"


Но ведь как я понял рассматривается эфективность кода, а не его правильность, а эфективность надо совместно с компилом глядеть.
Re[6]: Насколько оправдан данный вызов в цикле?
От: sux Земля  
Дата: 27.02.07 07:31
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>На x86 в зависимости от процессора сравнение может работать и быстрее, и так же, и медленнее. А быстрее работает модификация операнда / анализ результата на ноль/знак/etc.


jnz/jz и имелось ввиду
Re[7]: Насколько оправдан данный вызов в цикле?
От: Аноним  
Дата: 27.02.07 07:32
Оценка:
Здравствуйте, Alex Dav, Вы писали:

AD>в то что и надо — cont.GetLength() вызовется один раз

На спичках экономим...
Re[7]: Насколько оправдан данный вызов в цикле?
От: ДимДимыч Украина http://klug.org.ua
Дата: 27.02.07 07:47
Оценка:
Здравствуйте, sux, Вы писали:

ДД>>На x86 в зависимости от процессора сравнение может работать и быстрее, и так же, и медленнее. А быстрее работает модификация операнда / анализ результата на ноль/знак/etc.


sux>jnz/jz и имелось ввиду


Одна jcc погоды не сделает. Ньюанс вот:
первый вариант:
     inc eax
     cmp eax,CONST
     jbe LOOP_START

и второй:
     dec eax
     jnz LOOP_START
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[8]: Насколько оправдан данный вызов в цикле?
От: sux Земля  
Дата: 27.02.07 09:31
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, sux, Вы писали:


ДД>>>На x86 в зависимости от процессора сравнение может работать и быстрее, и так же, и медленнее. А быстрее работает модификация операнда / анализ результата на ноль/знак/etc.


sux>>jnz/jz и имелось ввиду


ДД>Одна jcc погоды не сделает. Ньюанс вот:

ДД>первый вариант:
ДД>
ДД>     inc eax
ДД>     cmp eax,CONST
ДД>     jbe LOOP_START
ДД>

ДД>и второй:
ДД>
ДД>     dec eax
ДД>     jnz LOOP_START
ДД>


дык в том то и дело, что будет сравнение НЕ с const! а со занчением в памяти т.е.

cmp eax,[ebp-xxx]

Re[9]: Насколько оправдан данный вызов в цикле?
От: ДимДимыч Украина http://klug.org.ua
Дата: 27.02.07 10:01
Оценка:
Здравствуйте, sux, Вы писали:

sux>дык в том то и дело, что будет сравнение НЕ с const! а со занчением в памяти т.е.


sux>
sux>cmp eax,[ebp-xxx] 
sux>

sux>

Да, такой фактор тоже присутствует.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.