Re[6]: передача по ссылке
От: Кодт Россия  
Дата: 10.11.06 16:44
Оценка: 17 (2)
Здравствуйте, night beast, Вы писали:

NB>теоретически Александреску может и прав, но компиляторы должны уметь оптимизировать это дело.

NB>и не известно, какой вариант более предпочтителен для оптимизации.

Передача по значению всё-таки предпочтительнее.
Пример:
extern void xxx();

void foo(int n)
{
    for(int i=0; i<n; ++i)
        xxx();
}

void bar(int const& n)
{
    for(int i=0; i<n; ++i)
        xxx();
}

/////////////////////////////

int global_n;
void xxx()
{
    --global_n;
}

int main()
{
    global_n = 100; foo(global_n);
    global_n = 100; bar(global_n);
}

В случае foo компилятор может установить, что на n (как и на i) нет никакого влияния извне, и сделать цикл от 0 до n так, как удобнее (например, с обратным отсчётом)
В случае bar таких гарантий нет (возможна ситуация, как xxx + main под чертой), и поэтому нужно перечитывать n на каждой итерации.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[7]: передача по ссылке
От: Константин Л. Франция  
Дата: 10.11.06 17:02
Оценка:
Здравствуйте, Кодт, Вы писали:

[]

К>В случае foo компилятор может установить, что на n (как и на i) нет никакого влияния извне, и сделать цикл от 0 до n так, как удобнее (например, с обратным отсчётом)

К>В случае bar таких гарантий нет (возможна ситуация, как xxx + main под чертой), и поэтому нужно перечитывать n на каждой итерации.

Это может произойти только в многопоточном окружении. Разве компилятор должен рассматривать такой случай?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: передача по ссылке
От: night beast СССР  
Дата: 11.11.06 11:26
Оценка:
Здравствуйте, Кодт, Вы писали:

NB>>теоретически Александреску может и прав, но компиляторы должны уметь оптимизировать это дело.

NB>>и не известно, какой вариант более предпочтителен для оптимизации.

К>Передача по значению всё-таки предпочтительнее.

К>Пример:
К>В случае foo компилятор может установить, что на n (как и на i) нет никакого влияния извне, и сделать цикл от 0 до n так, как удобнее (например, с обратным отсчётом)
К>В случае bar таких гарантий нет (возможна ситуация, как xxx + main под чертой), и поэтому нужно перечитывать n на каждой итерации.

Пример не совсем корректен, поскольку функции делают разные вещи, однако идею уловил. Спасибо.

В реальной ситуации по прежнему больше доверяю тестам
Re: Если уж сильно хочется...
От: Roman Odaisky Украина  
Дата: 11.11.06 12:08
Оценка:
template <class T>
inline void foo(T const& value)
{
    fooImpl<T>(value);
}

template <class T>
void fooImpl(boost::call_traits<T>::param_type value)
{
    . . .
}

Пара функций здесь требуется для того, чтобы автоматически вывести тип. Функцию-обертку оптимизатор, разумеется, выкинет.

Premature optimization is the root of all evil, помните!
До последнего не верил в пирамиду Лебедева.
Re[2]: передача по ссылке
От: remark Россия http://www.1024cores.net/
Дата: 11.11.06 16:34
Оценка:
Здравствуйте, Erlond, Вы писали:

E>Есть 3 способа передавать аргументы в функцию:


E>1). по значению;

E>2). по ссылке;
E>3). по указателю.

E>В 1-м случае создаётся временный объект, в который копируется значение аргумента, и функция работает с временным объектом. Внутри функции значения переданных аргументов можно изменять, это изменение никак не отразится за пределами функции. Недостаток — непроизводительные потери на создание временного объекта и копирование данных, что может быть достаточно накладно при больших объёмах.


E>Во 2-м случае функция получает адрес объекта и работает с ним напрямую, поэтому изменение значения аргумента, переданного функции по ссылке, будут видны за пределами функции. Это можно устранить, объявив ссылку константной. Достоинство — не происходит создания временного объекта и копирования даннных.


E>В 3-м случае почти то же самое, что и во 2-м, передаётся только указатель на данные, создания временного объекта не происходит. Отличия — указатель может быть NULL, при обращении к данным требуется операция разыменования (косвенная адресация).


Врменный объект создаётся всегда. Просто во втором и третем случаях временный объект — указатель. Соответственно, если размер объекта не больше размера указателя, то время на передачу одинаковое.
Во втором и третьем случае разыменование происходит одинакого.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: передача по ссылке
От: HiSH Россия http://m0riarty.ya.ru
Дата: 13.11.06 08:25
Оценка:
Здравствуйте, night beast, Вы писали:

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


КЛ>>>а что собенного в том, что интегральные типы передаются по ссылке?


N>>Тратиться дополнительное время на один уровень косвенности, а памяти отъедает меньше чем фактический тип только в случае long long;


NB>какие нибудь цифры, поддверждающие предположение имеются?


#include <iostream>

using namespace std;

int foo(int n){
        if (n > 1)
                return n * foo(n - 1);
        else
                return 1;
}

int boo(const int& n){
        if (n > 1)
                return n * boo(n - 1);
        else
                return 1;
}

int main(int argc, char** argv){
        cout << "sizeof(int): " << sizeof(int) << endl;
        cout << "sizeof(const int&): " << sizeof(const int&) << endl;
        if (argc == 2){
                if (argv[1][0] == '1'){
                        cout << "by value" << endl;
                        for (int i = 0; i < 10000000; i++)
                                foo(30);
                }
                if (argv[1][0] == '2'){
                        cout << "by const &" << endl;
                        for (int i = 0; i < 10000000; i++)
                                boo(30);
                }
        }
}



moriarty@earthquake:~$ time ./a.out 1
sizeof(int): 4
sizeof(const int&): 4
by value

real 0m2.705s
user 0m2.704s
sys 0m0.004s


moriarty@earthquake:~$ time ./a.out 2
sizeof(int): 4
sizeof(const int&): 4
by const &

real 0m3.056s
user 0m3.048s
sys 0m0.008s



moriarty@earthquake:~$ gcc --version
gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


"И все-таки, она вертится"
Re[8]: передача по ссылке
От: Кодт Россия  
Дата: 13.11.06 08:33
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Это может произойти только в многопоточном окружении.


Неправда. Мой пример однопоточный, и в нём всё происходит.

КЛ> Разве компилятор должен рассматривать такой случай?


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

Вот ещё один пример
int x = 0;
int *p = &x;
int i, n; // в этом месте переменные i и n строго локальны

for(i=0, n=10; i!=n; ++i) // и поэтому их можно разместить в регистрах
    --*p;                 // а то и вообще развернуть цикл

if(rand()%2)
    p = &n;
// начиная с этого места n может меняться извне
for(i=0, n=10; i!=n; ++i)
    --*p;
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: передача по ссылке
От: SWW Россия  
Дата: 13.11.06 11:01
Оценка:
R>Врменный объект создаётся всегда. Просто во втором и третем случаях временный объект — указатель. Соответственно, если размер объекта не больше размера указателя, то время на передачу одинаковое.

Время работы конструктора намного больше, чем время пересылки байтов. Поэтому double лучше передавать по значению, а CString — по ссылке, несмотря на то, что ее размер равен размеру указателя.

R>Во втором и третьем случае разыменование происходит одинакого.


Re[5]: передача по ссылке
От: night beast СССР  
Дата: 13.11.06 12:44
Оценка:
Здравствуйте, HiSH, Вы писали:

КЛ>>>>а что собенного в том, что интегральные типы передаются по ссылке?


N>>>Тратиться дополнительное время на один уровень косвенности, а памяти отъедает меньше чем фактический тип только в случае long long;


NB>>какие нибудь цифры, поддверждающие предположение имеются?


HSH>moriarty@earthquake:~$ time ./a.out 1

HSH>real 0m2.705s
HSH>user 0m2.704s
HSH>sys 0m0.004s


HSH>moriarty@earthquake:~$ time ./a.out 2
HSH>real 0m3.056s
HSH>user 0m3.048s
HSH>sys 0m0.008s



HSH>"И все-таки, она вертится"


угу
собственно, мой поинт был в том, что не стоит безоговорочно верить всему что говорят.
например, передача плейсхолдера по ссылке может быть более быстрой чем передача по значению.
по ситуации смотреть надо.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.