Я ++it вообще не использую принципиально. Потому что это малопонятная для человека конструкция, а язык программирования создавался для того, чтобы человек понимал, а не железяка. Да и мало кто использует, разве что кто её только изучил и хочет поприменять, после чего все вокруг страшно матерятся. Статья впрочем интересная с точки зрения что и на этих спичках можно как-то сэкономить.
gnawer: Я ++it вообще не использую принципиально. Потому что это малопонятная для человека конструкция, а язык программирования создавался для того, чтобы человек понимал, а не железяка. Конструкция it++ мне от чего-то не кажется более понятной, чем ++it. Эту тему я для себя давно закрыл - пишу it++ (только) тогда, когда требуется предыдущее значение it (практически никогда - это уже смахивает на tricky code). В остальных случаях - только ++it. На C++ лучше писать то, что действительно хочешь получить (и ни грамма лишнего), тогда твои желания (потенциально) не будут идти вразрез с тем, что заложено в компилятор.
А я, в последнее время, предпочитаю BOOST_FOREACH. Он избавляет меня от головной боли на тему с какой стороны поставить ++ :)
С вектором ситуация, в процессе оптимизации, возможно и сводится к тривиальной возне с указателями. Но итераторы бывают разные... Так что ++С все таки правильнее использовать.
Статейка занятная, только одно "НО" каждый раз при обсуждении рассматриваются просто вектор. у которого итератор в релизе = указатель. а если это map, а если это самописный контейнер со сложной логикой переходов между элементами или создание временного объекта сама по себе тяжелая операция, задачи-то у всех разные и объекты разные. В статье релизный вектор можно было смело заменить обычный массив и в релизе бы ничего не изменилось.
у Саттера с Александреску есть замечательная книга "C++ Coding Standards". Там даётся хорошее определение преждевременной оптимизации и "пессимизации" кода. Так вот, использование постфиксной формы операторов в местах, где подходит префиксная, авторы классифицируют как пессимизация, т.к. при одинаковых накладных расходах (сложность написания кода, его последующая поддержка и т.д.) получаем потенциально более медленный код.
Я бы от себя добавил, что при использовании этого принципа, глаза всегда "цепляются" за постфиксную форму. Ведь если автор кода её использовал, значит префиксная форма не подходит, значит, в этом месте надо быть повнимательнее.
Хотел запостить коммент на Хабре, но там как-то сложно получить аккаунт.
Решил проверить у себя на реальной программе для микроконтроллеров. Примерно 6к кода, 29 случаев ++/--. В резальтате код уменьшился на 4 байта, скорость работы не мерял, так как раз тут оно и не критично (да и не реально на фоне записи во флешь увидеть разницу).
Действительно статья на хабре бестолковая. Не вижу смысла сравнивать на скорость эти операторы, т.к. они используются в различных ситуациях. А при скорости современных ПК обращать внимание стоит только на суть возвращаемого значения.
Собственно разница в используемом регистре: eax для k++ и ecx для ++k. Данные получены в cl /Fa (Visual C++).
Кстати разница между s *= p; и s = s*p; так же будет такой (в регистре), только операции соответственные. А вот для более сложных объектов (вроде Вектора) имеет смысл уже выбирать (и ++it будет действительно предпочительнее по скорости).
Спасибо большое, разобрался: вся оптимизация на уровне машинных команд зависит от компилятора. Кстати, кому интересно, по данной теме есть забавная статья http://blog.emptycrate.com/node/329
В социальной сети поместил опросник, получил следующие результаты для разных компиляторов:
Алена, должно быть стыдно давать ссылки на такую ерунду.
ОтветитьУдалитьЯ ++it вообще не использую принципиально. Потому что это малопонятная для человека конструкция, а язык программирования создавался для того, чтобы человек понимал, а не железяка. Да и мало кто использует, разве что кто её только изучил и хочет поприменять, после чего все вокруг страшно матерятся. Статья впрочем интересная с точки зрения что и на этих спичках можно как-то сэкономить.
ОтветитьУдалитьgnawer, а почему по-вашему гугл это рекомендует?
ОтветитьУдалитьgnawer: Я ++it вообще не использую принципиально. Потому что это малопонятная для человека конструкция, а язык программирования создавался для того, чтобы человек понимал, а не железяка.
ОтветитьУдалитьКонструкция it++ мне от чего-то не кажется более понятной, чем ++it. Эту тему я для себя давно закрыл - пишу it++ (только) тогда, когда требуется предыдущее значение it (практически никогда - это уже смахивает на tricky code). В остальных случаях - только ++it. На C++ лучше писать то, что действительно хочешь получить (и ни грамма лишнего), тогда твои желания (потенциально) не будут идти вразрез с тем, что заложено в компилятор.
Почему ерунда-то?
ОтветитьУдалитьА с Маратом я согласен
А я, в последнее время, предпочитаю BOOST_FOREACH. Он избавляет меня от головной боли на тему с какой стороны поставить ++ :)
ОтветитьУдалитьС вектором ситуация, в процессе оптимизации, возможно и сводится к тривиальной возне с указателями. Но итераторы бывают разные... Так что ++С все таки правильнее использовать.
Статейка занятная, только одно "НО" каждый раз при обсуждении рассматриваются просто вектор.
ОтветитьУдалитьу которого итератор в релизе = указатель.
а если это map, а если это самописный контейнер со сложной логикой переходов между элементами или создание временного объекта сама по себе тяжелая операция, задачи-то у всех разные и объекты разные. В статье релизный вектор можно было смело заменить обычный массив и в релизе бы ничего не изменилось.
у Саттера с Александреску есть замечательная книга "C++ Coding Standards". Там даётся хорошее определение преждевременной оптимизации и "пессимизации" кода. Так вот, использование постфиксной формы операторов в местах, где подходит префиксная, авторы классифицируют как пессимизация, т.к. при одинаковых накладных расходах (сложность написания кода, его последующая поддержка и т.д.) получаем потенциально более медленный код.
ОтветитьУдалитьЯ бы от себя добавил, что при использовании этого принципа, глаза всегда "цепляются" за постфиксную форму. Ведь если автор кода её использовал, значит префиксная форма не подходит, значит, в этом месте надо быть повнимательнее.
Хотел запостить коммент на Хабре, но там как-то сложно получить аккаунт.
Решил проверить у себя на реальной программе для микроконтроллеров. Примерно 6к кода, 29 случаев ++/--.
ОтветитьУдалитьВ резальтате код уменьшился на 4 байта, скорость работы не мерял, так как раз тут оно и не критично (да и не реально на фоне записи во флешь увидеть разницу).
Да, забыл указать, компилятор SDCC
ОтветитьУдалить@Sergey Miryanov +1
ОтветитьУдалить@Dmitriy +1
Действительно статья на хабре бестолковая. Не вижу смысла сравнивать на скорость эти операторы, т.к. они используются в различных ситуациях. А при скорости современных ПК обращать внимание стоит только на суть возвращаемого значения.
Кстати, если кому интересно как на низком уровне, то разница на примере целымх (int) будет такой
ОтветитьУдалитьk++; vs. ++k;
int k = 1;
; Line 4
mov DWORD PTR _k$[ebp], 1
k++;
; Line 5
mov eax, DWORD PTR _k$[ebp]
add eax, 1
mov DWORD PTR _k$[ebp], eax
++k;
; Line 6
mov ecx, DWORD PTR _k$[ebp]
add ecx, 1
mov DWORD PTR _k$[ebp], ecx
Собственно разница в используемом регистре: eax для k++ и ecx для ++k. Данные получены в cl /Fa (Visual C++).
Кстати разница между s *= p; и s = s*p; так же будет такой (в регистре), только операции соответственные.
А вот для более сложных объектов (вроде Вектора) имеет смысл уже выбирать (и ++it будет действительно предпочительнее по скорости).
Привет всем, сейчас попробовал дизассемблировать через IDA PRO 2 объектных файла:
ОтветитьУдалить1)
void main()
{
int x = 1;
x++;
}
2)
void main()
{
int x = 1;
++x;
}
В коде следующее:
_main proc near
var_CC= byte ptr -0CCh
var_8= dword ptr -8
push ebp
mov ebp, esp
sub esp, 0CCh
push ebx
push esi
push edi
lea edi, [ebp+var_CC]
mov ecx, 33h ; '3'
mov eax, 0CCCCCCCCh
rep stosd
mov [ebp+var_8], 1
mov eax, [ebp+var_8]
add eax, 1
mov [ebp+var_8], eax
xor eax, eax
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
retn
_main endp
Как для первого, так и для второго случая, различий не нашел, компилятор VS 2010.
Получается, что компилятор сам распоряжается каким регистром ему в данном случае воспользоваться?
ОтветитьУдалитьAlexcnt
ОтветитьУдалитьПолучается, что компилятор сам распоряжается каким регистром ему в данном случае воспользоваться?
Создатели компилятора сами решают как им чего оптимизировать. Главное, чтобы оно Стандарту соответствовало.
Спасибо большое, разобрался: вся оптимизация на уровне машинных команд зависит от компилятора.
ОтветитьУдалитьКстати, кому интересно, по данной теме есть забавная статья http://blog.emptycrate.com/node/329
В социальной сети поместил опросник, получил следующие результаты для разных компиляторов:
1)
VS 2010
4, 5, 2, 5
12
12
2)
gcc 4.4.5
4, 5, 2, 5
9
9
3)
GNU C++ 4
4, 5, 2, 5
9
9
4)
MS Visual C++ 2005
3, 3, 2, 3
12
12
5)
Borland C++ 3.1
4, 4, 2, 2
12
12
6)
MS Visual C++ 1998
1,1,0,1
11
11
7)
Dev C++ v4
4,4,2,2
9
9
Алёна, скинул ссылку на ваш блог в ЖЖ (в своей первой статье)
ОтветитьУдалитьhttp://alexcnt.livejournal.com/619.html
По привычке уже пишу Алёна))
ОтветитьУдалить