Вызов какой функции быстрее?
В умных книгах пишут, что параметры в функцию лучше передавать типа unsigned const& par. Но ведь в данном случае оптимально: unsigned par. Или я не прав?
B>>Как правило, встроенные типы эффективнее передавать по значению.
P>Возможно. Но при передаче double, наверное будет небольшой выигрыш при передаче по ссылке (4 байта вместо 8).
Переписываться они будут не побайтно, так что и здесь лучше по значению.
Re[3]: func(int par) или func(int const& par)
От:
Аноним
Дата:
04.10.04 12:38
Оценка:
Здравствуйте, Privalov, Вы писали: P>Возможно. Но при передаче double, наверное будет небольшой выигрыш при передаче по ссылке (4 байта вместо 8).
еще все сильно зависит от ситуации (например, если передавать глобальную переменную, то для не ссылки будет четыре операции работы с памятью, а для ссылки — всего одна).
Вызов одинаковый, кстати Вопрос о времени работы.
А>В умных книгах пишут, что параметры в функцию лучше передавать типа unsigned const& par. Но ведь в данном случае оптимально: unsigned par. Или я не прав?
Прав, прав.
Если фунция именно такого размера, то компилятор встроит и тогда все равно.
Если не встроит, то есть две противовоположные тенденции:
если передавать по ссылке, то
+ снижаются затраты на копирование
— компилятор обращается все время к переменной через указатель (можно победить при помощи ключевого слова restrict или #pragma ivdep в IC++. restrict есть и в C99)
если передавать по значению, то
— снижаются затраты на копирование
+ компилятор обращается к копии переменной, которую может положить в регистр или вообще уничтожить каким-либо образом
Замечу, что в данном случае sizeof(ссылка) == sizeof(int), поэтому об оптимизации копирования речи не идет и лучше передать по значению.
Правильно работающая программа — просто частный случай Undefined Behavior
Так что все зависит от всего.
Если, скажем, фунkция работает в течение часа, то может оказаться, что передав туда слона std::map<std::string, std::string> MegaSlon программа начнет работать быстрее.
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, Аноним, Вы писали:
А>Во-втором случае на вызов, вроде, больше времени тратим.
Во-первых, почему времени? Больше инструкций еще не значит больше времени на современных процессорах. К тому же в release они, как-правило, так перемешаны, что трудно сказать, где начинается одна конструция С++, и начинается другая.
Во-вторых, ты случайно не в DebugMode компилировал? Если не принять специальных мер, то в Release компилиятор вообще уничтожит вызов этих функций.
В-третьих, ты передавал туда 123.
А если бы туда передавал не константу, а ссылку или разыменованный указатель, то код для второй фунции, наоборот, был бы короче.
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Аноним, Вы писали:
B>Как правило, встроенные типы эффективнее передавать по значению.
Интересно, почему? Передача по значению означает резервирование n байт в стеке. Если память нам некритична, то разницы нет — или мы работаем с памятью в стеке, или мы работаем с памятью, на которую передан указатель. Быстродействие одинаковое. Но заталкивание в стек параметров перед вызовом процедуры занимает некоторое время, пусть и незначительное. Так где же эффективность?
AFAIK, func(int const& par) нужно, чтобы компилятор сгенерировал предупреждение при попытке изменения par, т.к. в обоих случаях генерируется одинаковый код, по крайней мере на x86.
Здравствуйте, Privalov, Вы писали: B>>Как правило, встроенные типы эффективнее передавать по значению. P>Возможно. Но при передаче double, наверное будет небольшой выигрыш при передаче по ссылке (4 байта вместо 8).
А в случае с массивом выигрыш будет большой.
Здравствуйте, SWW, Вы писали:
B>>>Как правило, встроенные типы эффективнее передавать по значению.
P>>Возможно. Но при передаче double, наверное будет небольшой выигрыш при передаче по ссылке (4 байта вместо 8). SWW>Переписываться они будут не побайтно, так что и здесь лучше по значению.
Как понять "Переписываться они будут не побайтно"?
Re[3]: func(int par) или func(int const& par)
От:
Аноним
Дата:
04.10.04 15:02
Оценка:
Здравствуйте, glyph, Вы писали:
B>>Как правило, встроенные типы эффективнее передавать по значению. G> Интересно, почему? Передача по значению означает резервирование n байт в стеке. Если память нам некритична, то разницы нет — или мы работаем с памятью в стеке, или мы работаем с памятью, на которую передан указатель. Быстродействие одинаковое. Но заталкивание в стек параметров перед вызовом процедуры занимает некоторое время, пусть и незначительное. Так где же эффективность?
Да, но ведь в одном случае, наверное, будет использоваться mov, а во втором lea. Вот, наверное, и есть выйгрышь, хоть и микроскопический
З.Ы.: М-да. Мнения разошлись. Так как правильно все-таки?
Здравствуйте, Аноним, Вы писали:
А>Вызов какой функции быстрее? А>В умных книгах пишут, что параметры в функцию лучше передавать типа unsigned const& par. Но ведь в данном случае оптимально: unsigned par. Или я не прав?
Если только у тебя не цикл в 100000000000000000...0000000000000 раз повторений, то не экономь на спичках. Существенная разница — для реализованных классов, бо там либо вызывается, либо не вызывается конструктор копирования.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
А>Вызов какой функции быстрее? А>В умных книгах пишут, что параметры в функцию лучше передавать типа unsigned const& par. Но ведь в данном случае оптимально: unsigned par. Или я не прав?
самая умная книга, которая тебе все расскажет о твоем компиляторе и его оптимизаторе — это профайлер. Все остальное — спекуляции.
Здравствуйте, glyph, Вы писали:
G>Здравствуйте, Bell, Вы писали:
B>>Здравствуйте, Аноним, Вы писали:
B>>Как правило, встроенные типы эффективнее передавать по значению. G> Интересно, почему?
Потому что передача по ссылке добавляет уровень косвенности для доступа к значению переменной. Кроме того, если аргумент -- ссылка, то компилятор в ряде случаев будет генерить временные объекты при вызове. И, наконец, задание аргумента по ссылке уменьшает возможности по оптимизации кода, поскольку оптимизатор будет иметь меньше возможностей по выявлению побочных эффектов.
Стоит заметить ещё, что передача аргумента по значению и по ссылке семантически не эквивалентны.
G>Передача по значению означает резервирование n байт в стеке. Если память нам некритична, то разницы нет — или мы работаем с памятью в стеке, или мы работаем с памятью, на которую передан указатель. Быстродействие одинаковое. Но заталкивание в стек параметров перед вызовом процедуры занимает некоторое время, пусть и незначительное. Так где же эффективность?
Здравствуйте, Шахтер, Вы писали:
Ш>Потому что передача по ссылке добавляет уровень косвенности для доступа к значению переменной. Кроме того,
Гм. Не настолько это важно. Ш> если аргумент -- ссылка, то компилятор в ряде случаев будет генерить временные объекты при вызове. И,
Да, действительно... Я Ш>А ссылку в стек можно засунуть без затрат?
Однозначно ответить не могу.
Здравствуйте, Mikka77, Вы писали:
M>Здравствуйте, glyph, Вы писали:
G>> А в случае с массивом выигрыш будет большой.
M>Так массивы и так всегда по ссылке передаются
Не совсем так. Тип массива приводится к типу соответствующего указателя (а не ссылки).
Хочешь быть счастливым — будь им!
Без булдырабыз!!!