Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Объекты функций обычно работают быстрее функций, Так говорит Джосьютис в своей книге... 
:(
    Опции темы
EvilsInterrupt
Дата 15.12.2012, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Читая книгу Джосьютиса "C++. Стандартная библиотека" русское издание от 2004 года столкнулся с мыслью от автора на стр.136 где он приводит преимущества использования объектов функций. 

Мысль такая: "Шаблоны обычно лучше оптимизируются чем функции, поскольку на стадии компиляции доступно больше информации".

На мой взгляд обычная ф-ция доступна в том же объеме компилятору насколько доступен объект функции.

Вопросы: Почему автор так утверждает? Это действительно так?
PM MAIL WWW ICQ Jabber   Вверх
EvilsInterrupt
Дата 15.12.2012, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Кажется нашел здесь такое пояснение:

Цитата

Причина проста - объекты функций обеспечивают более эффективный код. В книге Скотта Мейерса на этот случай приводится пример с функцией std::sort - использование объектов функций всегда работает быстрее, выигрыш в скорости может составлять от 50% до 160%. Объясняется все тривиально - при использовании объекта функции компилятор способен встроить передаваемую функцию в тело алгоритма, а при использовании обычной функции встраивания не производится. 


Но насколько это отражает реальное положение дел?
PM MAIL WWW ICQ Jabber   Вверх
volatile
Дата 15.12.2012, 14:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(EvilsInterrupt @  15.12.2012,  12:38 Найти цитируемый пост)
Но насколько это отражает реальное положение дел? 

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

PM MAIL   Вверх
W4FhLF
Дата 15.12.2012, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Функцию можно определить как inline, тогда компилятор тоже постарается её встроить.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
EvilsInterrupt
Дата 15.12.2012, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



volatile, 
Даже если поставить перед обычными функциями слово inline ?

Добавлено через 21 секунду
W4FhLF, 
Опередил )))
PM MAIL WWW ICQ Jabber   Вверх
volatile
Дата 15.12.2012, 23:42 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(volatile @  15.12.2012,  14:45 Найти цитируемый пост)
когда-то я замерял стл-овские алгортимы,

Давненько это уже было... щас я покапался в своих архивах. 
Нашел таки. вот небольшой отрывок тех старых результатов
Код

 Сравнение скоростей сортировки. STL c функтором, STL с функцией и qsort
 Результаты  (запускалось при LOOP=2000000)

                          I         II         III
 1.STL c функтором     265278 us  265475 us  264615 us  *sort
 1.STL c функтором     340669 us  342627 us  342112 us  *stable_sort
 2.STL с функцией      404181 us  411751 us  409956 us  *sort
 2.STL с функцией      436370 us  437983 us  436325 us  *stable_sort
 3.qsort               550263 us  549610 us  549178 us

quiksort в 2 раза медленнее чем STL c функтором
STL с функцией медленнее чем STL c функтором.
(добавление inline к funkcia ничего не меняет.)

Римские цифры, это просто прогоны.
us - микросекунды.
остальное понятно.
Конкретные цифры, как вы понимаете не важны, но общая тенденция - довольно наглядна

Цитата(EvilsInterrupt @  15.12.2012,  15:26 Найти цитируемый пост)
Даже если поставить перед обычными функциями слово inline ?

прочтите последнюю строчку. я ничего щас не менял. (да собственно какой мне интерес что-то менять?)

Добавлено через 2 минуты и 29 секунд
Да, возможно вы спросите почему инлайн ничего не меняет.
Там компилировалось с макс. оптимизацией на скорость, в том числе:
/Ob2 (inline = any suitable)
Все результаты в общем и так инлайн.  smile


PM MAIL   Вверх
Alca
Дата 16.12.2012, 09:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



volatile, ну так выложи и тестовый код для полной картины

Это сообщение отредактировал(а) Alca - 16.12.2012, 09:09


--------------------
PM WWW ICQ Skype Jabber   Вверх
volatile
Дата 16.12.2012, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(Alca @  16.12.2012,  09:09 Найти цитируемый пост)
выложи и тестовый код 


Вот, например одна из тестовых функций:
Код

struct funktor : binary_function <int, int, bool> {
   bool operator() (int lhd, int rhd) const
   {
      return (lhd < rhd);
   }
};
bool funkcia (int lhd, int rhd)
{
   return (lhd < rhd);
}
int f_qsort(const void *pl, const void *pr)
{
   return (*(int*)(pl) - *(int*)(pr));
}
void time_compare()
{
    stopwatch sw;
    const int LOOP=2000000;
    //const int LOOP=100000;
    //const int LOOP=1000;
    vector<int> v;
    v.reserve(LOOP);
    for(int i=0; i<LOOP; ++i)
    {
        v.push_back(i);
    }

    myrnd mrnd;
    for(int i=0; i<10; ++i)
    {
       random_shuffle(v.begin(), v.end(), mrnd);
    }
    vector<int> vt(v);

    // Сначала с функтором
    sw.restart();
    sort(v.begin(), v.end(), funktor());
    sw.pause();
    sw.print("sort funktor()                  =", 1000000);

    // Затем с функтором (стабильная сортировка)
    v= vt;
    sw.restart();
    stable_sort(v.begin(), v.end(), funktor());
    sw.pause();
    sw.print("stable_sort funktor()           =", 1000000);

    //Затем с функцией
    v= vt;
    sw.restart();
    sort(v.begin(), v.end(), funkcia);
    sw.pause();
    sw.print("sort funkcia                    =", 1000000);
    
    //Затем с функцией  (стабильная сортировка)
    v= vt;
    sw.restart();
    stable_sort(v.begin(), v.end(), funkcia);
    sw.pause();
    sw.print("stable_sort funkcia             =", 1000000);
    
    //И наконец квиксорт
    v= vt;
    sw.restart();
    qsort( &v[0], v.size(), sizeof (int),  f_qsort );
    sw.pause();
    sw.print("qsort                           =", 1000000);

    //make_haep
    v= vt;
    sw.restart();
    make_heap(v.begin(), v.end(), funktor());
    sw.pause();
    sw.print("make_heap funktor()             =", 1000000);

    //make_haep
    v= vt;
    sw.restart();
    make_heap(v.begin(), v.end(), funkcia);
    sw.pause();
    sw.print("make_heap funkcia               =", 1000000);

    //sort_haep funktor()
    v= vt;
    make_heap(v.begin(), v.end(), funktor());
    sw.restart();
    sort_heap(v.begin(), v.end(), funktor());
    sw.pause();
    sw.print("sort_heap funktor()             =", 1000000);

    //sort_haep funkcia
    v= vt;
    make_heap(v.begin(), v.end(), funkcia);
    sw.restart();
    sort_heap(v.begin(), v.end(), funkcia);
    sw.pause();
    sw.print("sort_heap funkcia               =", 1000000);

    //partial_sort funktor()
    v= vt;
    sw.restart();
    partial_sort(v.begin(), v.end(), v.end(), funktor());
    sw.pause();
    sw.print("partial_sort funktor()          =", 1000000);

    //partial_sort funkcia
    v= vt;
    sw.restart();
    partial_sort(v.begin(), v.end(), v.end(), funkcia);
    sw.pause();
    sw.print("partial_sort funkcia            =", 1000000);

    
    //partial_sort /3 funktor()
    v= vt;
    sw.restart();
    partial_sort(v.begin(), v.begin() + v.size()/3, v.end(), funktor());
    sw.pause();
    sw.print("partial_sort /3 funktor()       =", 1000000);

    //partial_sort /3funkcia
    v= vt;
    sw.restart();
    partial_sort(v.begin(), v.begin() + v.size()/3, v.end(),  funkcia);
    sw.pause();
    sw.print("partial_sort /3 funkcia         =", 1000000);

}

Здесь используется еще секундомер. (вот старая версия, использовавшаяся с этим кодом)

stopwatch.h
Код

#ifndef BxXMmQpkiGCiA_stopwatch_h_incl
#define BxXMmQpkiGCiA_stopwatch_h_incl
//======================================================================================================= 
//
// Класс секундомера, для измерения временных интервалов
//
//======================================================================================================= 
class stopwatch {
   LARGE_INTEGER m_time;
   bool f_on;
public:
//-------------------------------------------------------------------------------------------------------   
// Конструктор по умолчанию. Сразу запускает секундомер.
   stopwatch() { restart(); }
//-------------------------------------------------------------------------------------------------------   
// Конструктор с параметром. Если (f_start==true) - запускает секундомер,
// иначе создает в сброшенном и остановленном состоянии
   stopwatch(bool f_start) 
   { 
       f_start ? restart() : reset();
   }
//-------------------------------------------------------------------------------------------------------   
// Сбрасывает и Запускает секундомер
   void restart() 
   { 
      f_on=true; 
      QueryPerformanceCounter(&m_time);
   }
//-------------------------------------------------------------------------------------------------------   
// Сбрасывает и Останавливает секундомер
   void reset()
   {
      f_on = false;
      m_time.QuadPart = 0;
   }
//-------------------------------------------------------------------------------------------------------   
// Информация о состоянии
// Если секундомер запущен возвращает true, если в паузе то false;
   bool get_state() const {return f_on;}
//-------------------------------------------------------------------------------------------------------   
// Переключает по очереди pause/resume (стоп/пуск), возвращает новое состояние после переключения.
   bool pause_resume()
   {
      LARGE_INTEGER now;
      QueryPerformanceCounter(&now);
      m_time.QuadPart = now.QuadPart - m_time.QuadPart;
      return f_on = !f_on;
   }
//-------------------------------------------------------------------------------------------------------   
// если f_resume==true запускает, иначе останавливает секундомер
   void pause_resume(bool f_resume) { if (f_on == !f_resume) pause_resume(); }
//-------------------------------------------------------------------------------------------------------   
// Останавливает
   void pause() { if (f_on) pause_resume(); }
//-------------------------------------------------------------------------------------------------------   
// Запускает
   void resume() { if (!f_on) pause_resume(); }
//-------------------------------------------------------------------------------------------------------   
// возвращает показание секундомера в <микро/милли/секундах>  
// koef 1-sec; 1000-msec; 1000000-usec
   unsigned int get_time(unsigned int koef=1000) const 
   {
      LARGE_INTEGER freq;   // Системная частота
      QueryPerformanceFrequency(&freq);
      if (f_on)
      {
         LARGE_INTEGER now;
         QueryPerformanceCounter(&now);
         return (((now.QuadPart - m_time.QuadPart) * koef) / freq.QuadPart);
      }
      else
      {
         return ((m_time.QuadPart * koef) / freq.QuadPart);
      }
   }
//-------------------------------------------------------------------------------------------------------   
// Печатает показание секундомера
// koef 1-sec; 1000-msec; 1000000-usec
   void print(const char* pname, unsigned int koef=1000) const
   {
      double t = get_time(koef*10)/10.0;
      if (pname == NULL) pname = "";
      const char* p = "??";
      if (koef==1) p = "sec";
      else if (koef==1000) p = "ms";
      else if (koef==1000000) p = "us";

      std::cout << boost::format("%s %9.1f %s\n") % pname % t % p;
   };                                               
//-------------------------------------------------------------------------------------------------------   
// Печатает показание секундомера
// koef 1-sec; 1000-msec; 1000000-usec
   void print(unsigned int koef=1000) const { print (NULL, koef); }
//--------------------------------------------------------------------------------------------------------

// ---------------  Дальше идут служебные и редко используемые --------------------------------------------

//--------------------------------------------------------------------------------------------------------
// получить get_time_raw
   unsigned __int64 get_time_raw() const
   {
      if (f_on)
      {
         LARGE_INTEGER now;
         QueryPerformanceCounter(&now);
         return (now.QuadPart - m_time.QuadPart);
      }
      else
      {
         return m_time.QuadPart;
      }
   }

//--------------------------------------------------------------------------------------------------------
// получить системную частоту (u64)
   static unsigned __int64 get_frequency()
   {
      LARGE_INTEGER freq;   // количество отсчетов в секунду
      QueryPerformanceFrequency(&freq);
      return freq.QuadPart;
   }

//--------------------------------------------------------------------------------------------------------
// получить текущий счетчик системы (u64)
   static unsigned __int64 get_counter()
   {
      LARGE_INTEGER now;
      QueryPerformanceCounter(&now);
      return now.QuadPart;
   }

//--------------------------------------------------------------------------------------------------------
// Получить int для посева (seed) генератора случайных чисел
// возвращает некое число зависящее от системного счётчика.
   static int get_randomizer()
   {
      LARGE_INTEGER now;
      QueryPerformanceCounter(&now);
      return now.LowPart ^ now.HighPart;
   }
};


#endif//BxXMmQpkiGCiA_stopwatch_h_incl


так, что еще?
myrnd - генератор случайных чисел, используйте любой, решающего значения не имеет.

У меня такое ошущение, что я результаты здесь уже публиковал. (щас поищу)

Добавлено через 3 минуты и 15 секунд
да, результаты здесь уже постил


PM MAIL   Вверх
W4FhLF
Дата 16.12.2012, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(volatile @  16.12.2012,  10:36 Найти цитируемый пост)

bool funkcia (int lhd, int rhd)
{
   return (lhd < rhd);
}


Я думал здесь должен быть inline? /Ob2 ещё не даёт гарантии, что она инлайн. 
Плюс надо добавить const по аналогии с funcktor, т.к. это влияет на оптимизацию.

Объективно, разницы между таким элементарным функтором и функцией быть недолжно. 



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
volatile
Дата 16.12.2012, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(W4FhLF @  16.12.2012,  13:28 Найти цитируемый пост)
Я думал здесь должен быть inline?

Цитата(volatile @  15.12.2012,  23:42 Найти цитируемый пост)
добавление inline к funkcia ничего не меняет


Цитата(W4FhLF @  16.12.2012,  13:28 Найти цитируемый пост)
Плюс надо добавить const 

инт передается по значению, зачем конст?

Добавлено через 1 минуту и 28 секунд
Цитата(W4FhLF @  16.12.2012,  13:28 Найти цитируемый пост)
по аналогии с funcktor

и там тоже по значению.

PM MAIL   Вверх
volatile
Дата 16.12.2012, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(W4FhLF @  16.12.2012,  13:28 Найти цитируемый пост)
должен быть inline? /Ob2 ещё не даёт гарантии, что она инлайн. 

да и походу, добавление инлайн, тоже не дает никакой гарантии, что она будет инлайн.


PM MAIL   Вверх
EvilsInterrupt
Дата 16.12.2012, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Кой-чего интересного нашел на rsdn.ru : Производительность компиляторов С++
PM MAIL WWW ICQ Jabber   Вверх
feodorv
Дата 16.12.2012, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(W4FhLF @  16.12.2012,  14:28 Найти цитируемый пост)
Объективно, разницы между таким элементарным функтором и функцией быть недолжно. 

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


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
mes
Дата 16.12.2012, 22:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



мне видится это разница так:
Цитата(volatile @  16.12.2012,  09:36 Найти цитируемый пост)
   sort(v.begin(), v.end(), funktor());

Код

template<typename T>
void do_some() {  T()();  } 


Цитата(volatile @  16.12.2012,  09:36 Найти цитируемый пост)
    sort_heap(v.begin(), v.end(), funkcia);

Код

void do_some(void (*fn)()) { fn(); }



--------------------
PM MAIL WWW   Вверх
mes
Дата 17.12.2012, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(volatile @  16.12.2012,  18:41 Найти цитируемый пост)
да и походу, добавление инлайн, тоже не дает никакой гарантии, что она будет инлайн.

(даже неявное) взятие адреса отменяет инлайн.. (для этого случая использования)


--------------------
PM MAIL WWW   Вверх
W4FhLF
Дата 17.12.2012, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



mes, интересно... а что будет если туда написать lambda function?


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
borisbn
Дата 17.12.2012, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(W4FhLF @  17.12.2012,  12:05 Найти цитируемый пост)
интересно... а что будет если туда написать lambda function? 

то же, что и функтором - http://liveworkspace.org/code/DAqxc$7


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alca
Дата 17.12.2012, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Даже с:
Код

#define ALWAYS_INLINE inline __attribute__((__always_inline__))


Цитата

stdout: 
func : 275 ms
functor : 196 ms
lambda : 191 ms
z : 189 ms


http://liveworkspace.org/code/1M9JFU$0


--------------------
PM WWW ICQ Skype Jabber   Вверх
volatile
Дата 17.12.2012, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Вообще-то, то что вызовы разные, у меня и не вызывало никогда сомнений.
Да хотя бы потому что Функтор - это _thiscall, Функция - это _cdecl
Можно конечно смотреть асемблерный код, и выщитывать такты.
Но это уже чисто академический интерес.

А в то время для меня вопрос звучал примерно так:
Вызов функции и функтора - безусловно разные вызовы, и нужно выяснить какой из них быстрее, чтобы использовать на приктике
ответ на это вопрос я получил (чем кстати и поделился).


PM MAIL   Вверх
mes
Дата 17.12.2012, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(volatile @  17.12.2012,  12:33 Найти цитируемый пост)
хотя бы потому что Функтор - это _thiscall, Функция - это _cdecl

только вот фокус в том, что используя в функторе ту самую функцию, выполняться сортировка будет быстрей, нежели с переданной функцией smile

Добавлено через 7 минут и 35 секунд
Цитата(W4FhLF @  17.12.2012,  11:05 Найти цитируемый пост)
а что будет если туда написать lambda function? 

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

Добавлено через 9 минут и 10 секунд
Цитата(volatile @  17.12.2012,  12:33 Найти цитируемый пост)
безусловно разные вызовы, и нужно выяснить какой из них быстрее, чтобы использовать на приктике

сорри, я подумал, что все ж также интересно в чем лежит эта разница, чтоб можно было не бездумно, а аргументировано применять на приктике  smile 

Это сообщение отредактировал(а) mes - 17.12.2012, 18:58


--------------------
PM MAIL WWW   Вверх
Alca
Дата 17.12.2012, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Надо разобрать асм код, делов то


--------------------
PM WWW ICQ Skype Jabber   Вверх
borisbn
Дата 17.12.2012, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



ждём пока на LWS появится такая возможность. boostcoder обещал


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 17.12.2012, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(mes @  17.12.2012,  18:58 Найти цитируемый пост)
 я подумал, что все ж также интересно в чем лежит эта разница, чтоб можно было не бездумно, а аргументировано применять на приктике   

mes, , это называется инкапсуляция.  smile
всмысле, не забивать голову всякой ерундой.
(пусть над этим думают разработчики компиляторов. это их приватная часть.)

Да, в конце концов, там не такая уж принципиальная разница.
Так ли уж важны эти проценты?


PM MAIL   Вверх
W4FhLF
Дата 17.12.2012, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



В действительности, общее объяснение и понимание более ценны, нежели частные субъективные тесты. Обычно, конечно, всё начинается с тестов, но то, что докопались до сути -- хорошо. 

Это сообщение отредактировал(а) W4FhLF - 17.12.2012, 23:54


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
volatile
Дата 18.12.2012, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(W4FhLF @  17.12.2012,  23:40 Найти цитируемый пост)
 частные субъективные тесты

W4FhLF, Мне очень жаль, что тесты не совпали с вашими ожиданиями...
сорри, если что...

PM MAIL   Вверх
mes
Дата 18.12.2012, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(volatile @  17.12.2012,  22:17 Найти цитируемый пост)
всмысле, не забивать голову всякой ерундой.

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



--------------------
PM MAIL WWW   Вверх
vinter
Дата 19.12.2012, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



mes, отличная идея. Когда меня спросили по поводу этой разницы я сразу отверг её, т.к. забыл о разнице в передаче. Поэтому слова Джосьюттиса и Майерса являются верными для своего времени. Но это не совсем верно для современности, где компиляторы могут встроить подобную конструкцию. Никто не мешает встроить алгоритм STL после чего пропадет всякое взятие адреса и функция может быть встроена.
Поэтому получается, что в общем случае функторы могут быть быстрее, но это далеко не обязательно. Использование шаблонных функций вполне может быть встроено, так же как и функтор.

Не знаю, может быть это влияние перевода, но, по факту, в издании 2012 года он менее категоричен:
Цитата

The concept of templates using usually allows better optimization because more details are defined at compile time. Thus, passing function objects instead of ordinary functions often results in better performance.


Это сообщение отредактировал(а) vinter - 19.12.2012, 14:12


--------------------
Мой блог
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 19.12.2012, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Справедливости ради стоит привести и слова Джосьютиса из русского издания:
Цитата

Объекты функции обычно работают быстрее функций. Шаблоны обычно лучше оптимизируются, поскольку на стадии компиляции доступно больше информации. Следовательно, передача объекта функции вместо обычной функции часто повышает быстродействие программы.


PM MAIL WWW ICQ Jabber   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0795 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.