Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 28, средняя оценка - 4.75
kvadro
11 / 9 / 1
Регистрация: 12.03.2012
Сообщений: 127
#1

const float & - C++

15.11.2013, 15:08. Просмотров 4029. Ответов 92
Метки нет (Все метки)

Заметил что часто передают и возвращают const float & ( например в мат либах ), вместо простой передачи значения.

Возникает вопрос: В чём плюс использования const float & вместо обычного float?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.11.2013, 15:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос const float & (C++):

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration? - C++
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const Rational&amp;); - invalid function declaration. ...

Что это bool operator== (const CLASS&) const; - C++
Что это? class CLASS { public: bool operator== (const CLASS&amp;) const; ...

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка? - C++
void Array::getArray() // вывод массива { for (int ix = 0; ix &lt; size; ix++) cout &lt;&lt; setw(5) &lt;&lt; ptr; // вывод элементов...

const& и const* в имени функции - C++
Объясните пожалуйста что значит const&amp; и const* в имени и параметрах функции(пример из Вандевурд,Джосаттис): template &lt;typename T&gt; ...

Ошибка: redeclaration of `const float PI' - C++
#include &lt;iostream&gt; using namespace std; int main () { int radiys; int total_okryznosti; int total_ploshadi; const...

#define PI or static const float PI - C++
Что лучьше обьясните? #define PI 3,14159265 или static const float PI=3,14159265;

92
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
15.11.2013, 21:37 #61
Цитата Сообщение от castaway Посмотреть сообщение
Так не замеряют.
Неужели? А как тогда?

Добавлено через 1 минуту
Кликните здесь для просмотра всего текста
Bash
user@linuxmint ~/Рабочий стол $ g++ game.cpp -ogame
user@linuxmint ~/Рабочий стол $ ./game
ref val
----------------
4.76    5.61
4.75    5.6
4.76    5.6
4.77    5.59
4.8 5.6
4.8 5.6
4.85    5.59
4.88    5.6
5.1 6.84
4.94    5.65
----------------
ref: 48.41
val: 57.28
user@linuxmint ~/Рабочий стол $ g++ game.cpp -ogame -O
user@linuxmint ~/Рабочий стол $ ./game
ref val
----------------
0.64    0.63
0.63    0.64
0.63    0.63
0.63    0.63
0.64    0.63
0.63    0.64
0.63    0.63
0.63    0.63
0.64    0.63
0.63    0.64
----------------
ref: 6.33
val: 6.33
user@linuxmint ~/Рабочий стол $ g++ game.cpp -ogame -O1
user@linuxmint ~/Рабочий стол $ ./game
ref val
----------------
0.66    0.66
0.64    0.65
0.63    0.63
0.65    0.66
0.65    0.65
0.65    0.65
0.65    0.64
0.64    0.64
0.66    0.65
0.66    0.66
----------------
ref: 6.49
val: 6.49
user@linuxmint ~/Рабочий стол $ g++ game.cpp -ogame -O2
user@linuxmint ~/Рабочий стол $ ./game
ref val
----------------
0   0
0   0
0   0
0   0
0   0
0   0
0   0
0   0
0   0
0   0
----------------
ref: 0
val: 0
user@linuxmint ~/Рабочий стол $ g++ game.cpp -ogame -O3
user@linuxmint ~/Рабочий стол $ ./game
ref val
----------------
0   0
0   0
0   0
0   0
0   0
0   0
0   0
0   0
0   0
0   0
----------------
ref: 0
val: 0
user@linuxmint ~/Рабочий стол $
0
castaway
15.11.2013, 21:39
  #62

Не по теме:

Цитата Сообщение от programina Посмотреть сообщение
А как тогда?
Должны быть четкие критерии.

0
lowercase
15.11.2013, 21:45
  #63

Не по теме:

Цитата Сообщение от kvadro Посмотреть сообщение
В чём плюс использования const float & вместо обычного float
можно разводить срачи на форумах, например

1
Evg
Эксперт CАвтор FAQ
17940 / 6171 / 412
Регистрация: 30.03.2009
Сообщений: 16,941
Записей в блоге: 27
16.11.2013, 00:25 #64
Цитата Сообщение от programina Посмотреть сообщение
А здесь? Очень криво?
Ты хочешь замерить как работает передача параметра в функцию. В этом случае надо запрещать инлайн. Но смысл всего деяния в том числе и в том, что в боевом режиме с оптимизациями инлайн должен работать. А потому непонятно, чего твой тест меряет. В режиме с оптимизациями он вырождается в пустышку. Как вариант запрещать инлайн и включить оптимизации - тогда замеришь время передачи параметров (насколько я понял, конкретно тебя волнует в первую очередь именно этот аспект). Но пример, который был описан в посте #4 в первую очередь подразумевает наличие инлайна
0
kvadro
11 / 9 / 1
Регистрация: 12.03.2012
Сообщений: 127
16.11.2013, 03:58  [ТС] #65
Evg
Без оптимизаций инлайн не сработает, но значение по ссылке браться не будет ибо оно будет лежать в регистре, по сути выходит +1 инструкция. Разницы нет. Завтра спрошу у самого автора, и в случае успеха отпишусь тут.
0
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
16.11.2013, 11:54 #66
Действительно, если вставить __attribute__ ((noinline)) перед названием функции, то по значению будет гораздо быстрее, чем по ссылке:
C++
#include <cstdio>
#include <ctime>
 
struct vec4 { float a[4]; };
 
// По ссылке
vec4 __attribute__ ((noinline)) ref(float &a, float &b, float &c, float &d) 
{ 
    vec4 v;
    v.a[0] = a;
    v.a[1] = b;
    v.a[2] = c;
    v.a[3] = d; 
    return v; 
}
// По значению
vec4 __attribute__ ((noinline)) val(float  a, float  b, float  c, float  d) 
{ 
    vec4 v;
    v.a[0] = a;
    v.a[1] = b;
    v.a[2] = c;
    v.a[3] = d; 
    return v; 
}
 
//vec4(*pref)(float &, float &, float &, float &) = ref;
//vec4(*pval)(float,   float,   float,   float  ) = val;
 
clock_t t;
long N = 100000000;
double sc = 1000000.0;
float x = 0.0;
float y = 0.0;
float z = 0.0;
float w = 0.0;
 
 
int main()
{
    vec4 vref;
    vec4 vval;
 
    for(int g = 0; g < 5; g++)
    {
        t = clock();
        for(int i = 0; i < N; i++) vref = ref(x, y, z, w);
        t = clock() - t;
        printf("ref: %2.2f\t", t/sc);
 
        t = clock();
        for(int i = 0; i < N; i++) vval = val(x, y, z, w);
        t = clock() - t;
        printf("val: %2.2f\n", t/sc);
    }
}


Добавлено через 42 секунды
Bash
user@linuxmint ~/Рабочий стол $ g++ test.cpp -otest -O3
user@linuxmint ~/Рабочий стол $ ./test
ref: 1.08   val: 0.38
ref: 1.10   val: 0.38
ref: 1.13   val: 0.38
ref: 1.10   val: 0.39
ref: 1.10   val: 0.38
0
castaway
Эксперт С++
4884 / 3019 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
16.11.2013, 12:54 #67
Только ты одного не учла, -O3 имеет приоритет над __attribute__ ((noinline)).
0
Evg
Эксперт CАвтор FAQ
17940 / 6171 / 412
Регистрация: 30.03.2009
Сообщений: 16,941
Записей в блоге: 27
16.11.2013, 12:55 #68
Цитата Сообщение от kvadro Посмотреть сообщение
но значение по ссылке браться не будет ибо оно будет лежать в регистре
Ссылка - это адрес. Если значение лежит в регистре - оно будет перемещено в стек. Без инлайна этот код будет работать заведомо медленнее. Инлайн может отсутствовать и в режиме с оптимизациями, если функция будет большого размера или определена в другом модуле. Поэтому для чистоты эксперимента в коротких тестах надо запрещать инлайн.

programina, тест теперь "хороший". В нем даже есть цикл. Цикл нужен как минимум по двум соображениям. Первая итерация цикла - разогрев (подкачка всех кодов и данных в кэш). Остальные итерации - чистая работа процессора. Несколько итераций нужны для усреднения времени из-за флуктуаций

На всякий случай в ref надо добавить const во все ссылки. На коротком примере это не должно влиять, но для чистоты эксперимента нужно сделать. Возможно, что время ref'а чуток улучшится
0
castaway
Эксперт С++
4884 / 3019 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
16.11.2013, 12:56 #69
Хотя... нет, не имеет. Просто GCC генерирует какую-то ерунду..
0
Evg
Эксперт CАвтор FAQ
17940 / 6171 / 412
Регистрация: 30.03.2009
Сообщений: 16,941
Записей в блоге: 27
16.11.2013, 13:00 #70
Кстати, чтобы сделать запрет инлайна на компиляторе не-gcc, то проще всего вызывать функцию через указатель на функцию. Такой код будет переносимым, в отличие от кода с __attribute__((noinline))
1
castaway
Эксперт С++
4884 / 3019 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
16.11.2013, 13:08 #71
Всё логично. В случае с ссылкой не создаются новые переменные, в случае с обычной переменной приходится их копировать, а это дополнительные инструкции fld и fstp на каждую переменную.

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от Evg Посмотреть сообщение
то проще всего вызывать функцию через указатель на функцию
.., ну или сделать её рекурсивной)

0
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
16.11.2013, 13:31 #72
А здесь по ссылке быстрее
C++
#include <cstdio>
#include <ctime>
 
struct mat4 { float a[16]; };
 
/// По ссылке
mat4 __attribute__ ((noinline)) ref(
    const float &a, const float &b, const float &c, const float &d,
    const float &e, const float &f, const float &g, const float &h,
    const float &i, const float &j, const float &k, const float &l,
    const float &m, const float &n, const float &o, const float &p
) 
{ 
    mat4 mtrx;
    mtrx.a[ 0] = a; mtrx.a[ 1] = b; mtrx.a[ 2] = c; mtrx.a[ 3] = d; 
    mtrx.a[ 4] = a; mtrx.a[ 5] = b; mtrx.a[ 6] = c; mtrx.a[ 7] = d; 
    mtrx.a[ 8] = a; mtrx.a[ 9] = b; mtrx.a[10] = c; mtrx.a[11] = d; 
    mtrx.a[12] = a; mtrx.a[13] = b; mtrx.a[14] = c; mtrx.a[15] = d; 
    return mtrx; 
}
/// По значению
mat4 __attribute__ ((noinline)) val(
    float a, float b, float c, float d,
    float e, float f, float g, float h,
    float i, float j, float k, float l,
    float m, float n, float o, float p
) 
{ 
    mat4 mtrx;
    mtrx.a[ 0] = a; mtrx.a[ 1] = b; mtrx.a[ 2] = c; mtrx.a[ 3] = d; 
    mtrx.a[ 4] = a; mtrx.a[ 5] = b; mtrx.a[ 6] = c; mtrx.a[ 7] = d; 
    mtrx.a[ 8] = a; mtrx.a[ 9] = b; mtrx.a[10] = c; mtrx.a[11] = d; 
    mtrx.a[12] = a; mtrx.a[13] = b; mtrx.a[14] = c; mtrx.a[15] = d; 
    return mtrx; 
}
 
/*
// Указатель на функцию "по-ссылке"
mat4(*pref)(
    const float&,const float&,const float&,const float&,  
    const float&,const float&,const float&,const float&,  
    const float&,const float&,const float&,const float&,  
    const float&,const float&,const float&,const float&
) = ref;
 
// Указатель на функцию "по-значению"
mat4(*pval)(
    float,float,float,float,  
    float,float,float,float,  
    float,float,float,float,  
    float,float,float,float
) = val;
*/
 
// глобальная дата
clock_t t;
long N = 100000000;
double sc = 1000000.0;
float a = 0.0;
float b = 0.0;
float c = 0.0;
float d = 0.0;
float e = 0.0;
float f = 0.0;
float g = 0.0;
float h = 0.0;
float i = 0.0;
float j = 0.0;
float k = 0.0;
float l = 0.0;
float m = 0.0;
float n = 0.0;
float o = 0.0;
float p = 0.0;
 
 
int main()
{
    mat4 mref;
    mat4 mval;
 
    for(int g = 0; g < 4; g++)
    {
        t = clock();
        for(int i = 0; i < N; i++) mref = ref(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
        t = clock() - t;
        printf("ref: %2.2f\t", t/sc);
 
        t = clock();
        for(int i = 0; i < N; i++) mval = val(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
        t = clock() - t;
        printf("val: %2.2f\n", t/sc);
    }
}
Bash
user@linuxmint ~/Рабочий стол $ g++ test.cpp -otest -O3
user@linuxmint ~/Рабочий стол $ ./test
ref: 0.64   val: 0.80
ref: 0.65   val: 0.80
ref: 0.63   val: 0.77
ref: 0.63   val: 0.80
0
castaway
Эксперт С++
4884 / 3019 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
16.11.2013, 13:34 #73
По ссылке всегда должно быть быстрее. Главное правильно построить тест.
0
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
16.11.2013, 13:34 #74
А если убрать __attribute__ ((noinline)) и вызывать функции через указатель на функцию, то по значению снова быстрее:
Bash
user@linuxmint ~/Рабочий стол $ g++ test.cpp -otest -O3
user@linuxmint ~/Рабочий стол $ ./test
ref: 1.12   val: 0.77
ref: 1.15   val: 0.78
ref: 1.11   val: 0.77
ref: 1.16   val: 0.80
Добавлено через 22 секунды
castaway, может все таки -O3 влияет?
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
16.11.2013, 13:35 #75
Цитата Сообщение от castaway Посмотреть сообщение

Не по теме:

.., ну или сделать её рекурсивной)

Главное, чтобы при этом constexpr не стояло.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.11.2013, 13:35
Привет! Вот еще темы с ответами:

Что значит const float PI = 3.14159F ? - C++
Для изучения С++ использую книгу Лафоре. На стр. 61 видим предложение: &quot;Если вам необходимо описать константу long, то после ее числового...

Error C2664: 'sprintf' : cannot convert parameter 2 from 'float' to 'const char *' - C++
Читаю в Интернете пишут о том что нужно явное преобразование типов, подскажите, пжл, как его произвести. PS: если оно тут...

(const string &) - C++
Есть класс class Someclass { public: Someclass( const string &amp;one ) { cout &lt;&lt; one; } };

Error C2440: return: невозможно преобразовать "const char *" в "const char (&)[6]" - C++
Вроде все правильно а все равно не работает. Подскажите в чем ошибка #include &lt;iostream&gt; template&lt;typename T&gt; inline const T...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
75
Yandex
Объявления
16.11.2013, 13:35
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru