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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.63
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
#1

адаптеры - C++

04.11.2011, 20:03. Просмотров 2073. Ответов 35
Метки нет (Все метки)

добрый вечер интересно ваше мнение.
такие вещи как адаптеры, биндеры позиционируются как шибко быстро работающие.
и рекомендуется ими активно пользоваться. Например вместо попыток определить собственную шаблон-функцию сравнения, которая сравнивает входное значение с неким фиксированным значением, рекомендуется юзать биндер, который сделает нам из функции less принимающей 2 параметра для сравнения, функтор принимающий одно значение. Все это делается через создание шаблонных структур ну или классов в которых один из параметров less становится членом, и имеется небезызвестный operator()() который и используют стандартные алгоритмы, когда мы даем на вход сий класс.
Так вот поделитесь мнением, действительно ли через биндеры это шибко быстрее, чем через просто функцию, на ваш взгляд? В процессе работы алгоритма ну например форич, при такой схеме во первых вызывается конструктор столько раз сколько элементов надо пройти, вызывается деструктор столько же раз, ну и вызывается сам operator()(). Это работает действительно быстрее, чем просто вызов какой либо своей функции? Как считаете?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.11.2011, 20:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос адаптеры (C++):

Функциональные адаптеры - C++
Для произвольного целочисленного массива данных написать функцию которая уменьшает все элементы в 2 раза с использованием функциональных...

Стандартные функторы-адаптеры - C++
Добрый вечер! Хочу отсортировать контейнер, заполненный указателями на объекты класса Class, критерий сортировки - метод этого класса. При...

Функторы, алгоритмы и адаптеры - C++
Нужна помощь! 1 Нужно создать multimap и multiset на основе элементов типа класса CPerson, содержащий в своем классе следующие...

Функторы, предикаты, функциональные адаптеры, лямбда-функции - C++
Вступление Статья ориентирована на программистов С++, поверхностно знающих/желающих узнать STL, в особенности, с использованием его...

Сетевые адаптеры! - Windows Server
Есть сервер DELL R320 под управлением Windows 2008 R2 Standart. Сняли с него образ. Имеется ещё один сервер DELL R610, RAID на нём создан с...

Адаптеры сети - Wi-Fi
Здравствуйте. Ноут asus n-series 76vb. После установки win10 начал барахлить wifi (самопроизвольно отключаться). А вчера совершенно...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
05.11.2011, 01:02 #16
ValeryLaptev, это уже отдельный тест
stl'ские функторы предназначены не только для массивов миллионной размерности
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
05.11.2011, 01:14 #17
Цитата Сообщение от alex_x_x Посмотреть сообщение
ValeryLaptev, это уже отдельный тест
stl'ские функторы предназначены не только для массивов миллионной размерности
В реальных задачах не обрабатывают один маленький массив миллион раз. А вот миллионные массивы - это ближе к реальности. У меня в задаче матрица - 625 миллионов узлов.
STL-ные алгоритмы давят на векторе по скорости любые мои "доморощенные" алгоритмы. Бывает, что совсем немного, процентов на 5-7-10, но выигрывают. Осталось только на ассемблерной вставке написать - только это еще не попробовал...
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
05.11.2011, 01:28 #18
ValeryLaptev, ну применение их общее
спор не идет об эффективности алгоритмов в связке с контейнерами(тут все и так очевидно) - речь идет об использовании адаптеров и биндеров
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
05.11.2011, 01:59 #19
Цитата Сообщение от alex_x_x Посмотреть сообщение
ValeryLaptev, ну применение их общее
спор не идет об эффективности алгоритмов в связке с контейнерами(тут все и так очевидно) - речь идет об использовании адаптеров и биндеров
Об эффективности использования, что и пытаются доказать измерениями.
Поэтому и нужно проверить на много миллионных массивах...
0
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
05.11.2011, 13:11 #20
Цитата Сообщение от AzaKendler Посмотреть сообщение
Я предполагаю что конструктор вызывается чтолько раз сколько объектов контейнера надо обойти, соответственно столько же раз вызовется деструктор и оператор ()()
Это так сложно проверить(чтобы убедиться, что это не так)?
Цитата Сообщение от AzaKendler Посмотреть сообщение
плюсом это все вызывается через функцию помощник.
Нет никаких функций помощников, через которые что-то там вызывается... Есть функции "редакторы связей", которые "связывают" параметр функции/функтора с определённым значение, и возвращают новый функтор. Всё это происходит до начала работы функции-алгоритма и никак не влияет на то, что будет происходить внутри.
Цитата Сообщение от AzaKendler Посмотреть сообщение
Но...разве так быстро как пишут?
Да. Все дело во встраивании.
Цитата Сообщение от AzaKendler Посмотреть сообщение
Нельзя сравнивать функцию и биндер? почему с? в этой картиночке биндер это как раз функция помощник которая генерит класс и подсовывает его в алгоритм, и уже оператор()() этого класса делает сравнение
Повторюсь, "редактор связей" не участвует в работе функции-алгоритма, в ней участвует функтор, cледовательно сравнивать можно только функтор и функцию.
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
05.11.2011, 13:36  [ТС] #21
Цитата Сообщение от rangerx Посмотреть сообщение
Повторюсь, "редактор связей" не участвует в работе функции-алгоритма, в ней участвует функтор, cледовательно сравнивать можно только функтор и функцию.
если я правильно понял - то что называется редактором связи не вызывается каждый раз при создании объекта? объект создается сам?
Страуструп расписал что биндер - это функция-шаблон, за которой спрятан еще и класс шаблон который она создает, и который содержит тот самый функтор используемый алгоритмами. Накропав и запустив - наблюдал именно такой эффект
редактор связей, ивашка, фишка - как ее не назови - она инстанцирует шаблон класса и генерит его временный экземпляр. Интересно узнать почему ее работу не надо учитывать?
в каждом проходе по элементу вектора работает связка - биндер-конструктор-функтор-деструктор.
это мы и сравнивали с простой функцией ну и с лямбдой. Если я ошибаюсь - буду рад изменить мнение на более точное

Добавлено через 3 минуты
Цитата Сообщение от rangerx Посмотреть сообщение
Это так сложно проверить(чтобы убедиться, что это не так)?
наверно где то я допустил ошибку. и это интересно. посмотри пожалуйста на приложенные выше картинки - от чего зависит сколько раз вызывается конструктор и деструктор временного объекта. или на твой взгляд объект не временный?
обладают ли временные объекты из стл "особыми" свойствами?

Добавлено через 5 минут
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Об эффективности использования, что и пытаются доказать измерениями.
Поэтому и нужно проверить на много миллионных массивах...
согласен - надо брать огромные выборки. но напрашивается вопрос. тенденция с увеличением количества элементов должна будет поменяться? т.е. например на малых объемах выигрывает лямбда или простая функция - увеличиваем на миллионы и...ого го - адаптеры рулят? Это так?
Это важный момент и если есть возможность то хотелось бы увидеть результат тестов тут с теми же что показали парни
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
05.11.2011, 14:16 #22
Цитата Сообщение от AzaKendler Посмотреть сообщение
если я правильно понял - то что называется редактором связи не вызывается каждый раз при создании объекта? объект создается сам?
Страуструп расписал что биндер - это функция-шаблон, за которой спрятан еще и класс шаблон который она создает, и который содержит тот самый функтор используемый алгоритмами. Накропав и запустив - наблюдал именно такой эффект
редактор связей, ивашка, фишка - как ее не назови - она инстанцирует шаблон класса и генерит его временный экземпляр. Интересно узнать почему ее работу не надо учитывать?
в каждом проходе по элементу вектора работает связка - биндер-конструктор-функтор-деструктор.
это мы и сравнивали с простой функцией ну и с лямбдой. Если я ошибаюсь - буду рад изменить мнение на более точное
И инстанцирование шаблона, и редактирование связей работают на этапе создания программы, а не на этапе выполнения.
А вот создание временного объекта - на этапе выполнения.

По поводу малых-больших размеров контейнеров. Прямая аналогия с написанием процедуры. Если процедура вызывается один раз, то смысла ее писать нет. Выгоды от процедуры возникают только тогда, когда она написана один раз, а вызывается много раз.
Другая аналогия: применение двоичного поиска.
При линейном поиске выполняется в среднем n/2 сравнений; при двоичном поиске - log(n) сравнений. Но для применения двоичного поиска надо массив отсортировать., что требует n*log(n) операций. Тогда возникает задача: при каких n выгоден двоичный поиск.
Для этого надо решить неравенство:
k*n/2 > nlog(n) + k*log(n)
чтобы выяснить, при каких k (количество поисков) и n (размер массива) количество операций линейного поиска начинает превышать количество операций при двоичном поиске.
1
ForEveR
В астрале
Эксперт С++
7973 / 4735 / 321
Регистрация: 24.06.2010
Сообщений: 10,542
Завершенные тесты: 3
05.11.2011, 14:26 #23
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <algorithm>
#include <vector>
#include <functional>
 
bool more_then_7(int value)
{
        return value > 7;
}
 
int main()
{
        std::vector<int> v(1000000);
        const size_t size = v.size();
        for (size_t i=0;i<size;++i)
        {
#ifdef LAMBDA
                std::find_if(v.begin(), v.end(), [](const int value) {return value > 7;});
#else
                std::find_if(v.begin(), v.end(), more_then_7);
#endif
        }
}
Bash
1
2
3
4
5
6
7
8
9
10
forever@lavroffff:~/Programs$ g++ -O3 -o map_test map_test.cpp -std=c++0x && time ./map_test 
 
real    0m0.019s
user    0m0.000s
sys 0m0.004s
forever@lavroffff:~/Programs$ g++ -O3 -DLAMBDA -o map_test map_test.cpp -std=c++0x && time ./map_test 
 
real    0m0.010s
user    0m0.000s
sys 0m0.004s
Тесты показывают примерно одинаково.
0
Mr.X
Эксперт С++
3049 / 1694 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
05.11.2011, 14:28 #24
Цитата Сообщение от rangerx Посмотреть сообщение
Цитата Сообщение от AzaKendler Посмотреть сообщение
Я предполагаю что конструктор вызывается чтолько раз сколько объектов контейнера надо обойти, соответственно столько же раз вызовется деструктор и оператор ()()
Это так сложно проверить(чтобы убедиться, что это не так)?
Ну а если поизучать алгоритм for_each, то можно заметить, что он возвращает функтор, оператор () которого вызывался для всех обойденных объектов, и в котором за время обхода могла накопиться нужная пользователю информация.
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
05.11.2011, 17:02  [ТС] #25
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
И инстанцирование шаблона, и редактирование связей работают на этапе создания программы, а не на этапе выполнения.
А вот создание временного объекта - на этапе выполнения.
собственно нигде и не было сказано нечто противоречащее этой истине.

Спасибо Валерий много интересной информации. Единственное что смутило меня и почему я задал вопрос - это утверждение Страуструпа о том, что вся эта конструкция будет работать быстрее.
Если честно, то пока я не увидел что это так, скорее наоборот ну и в лучшем случае, приблизительно равно.И единственный очевидный плюс - это шаблонность адаптеров, позволяющая работать с разными типами. возможно есть еще плюсы

Добавлено через 4 минуты
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну а если поизучать алгоритм for_each, то можно заметить, что он возвращает функтор, оператор () которого вызывался для всех обойденных объектов, и в котором за время обхода могла накопиться нужная пользователю информация.
хорошее инфо. надо поизучать. в свете этого вопрос. Временный объект класса для биндера, который содержит оператор()() создается и уничтожается все время. Каким образом оператор()(), который является членом этого класса может быть сохранен при разрушении? Ну чтобы не вызывался каждый раз новый, а был один и тот же? мне кажется что вызываются биндер-конструктор-оператор()()-less-деструктор каждый раз.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <class BO> class Binder: public unary_function <typename BO::first_argument_type,typename BO::result_type>
 {
 
     BO b;
     typename BO::second_argument_type A2;
 public:
 
  ~Binder(){};
 Binder(const BO& rb,const typename BO::second_argument_type& a2):b(rb),A2(a2){};
 
 result_type operator ()(const argument_type& x)const {return b(x,A2); } //+вызов less
 
 };
 
 
 template <class BO,class T> Binder<BO> construct (const BO& op, const T& v)
 {
 
     return Binder<BO>(op,v);
 };
эту бодягу я и пускал в эксперимент. считайте что это копи паст из Страуструпа. просто набирал, чтобы понять как оно запускается.
поэтому имена свои.
в дебаге в студии - хорошо видно пошагово что вызывается при проходе вектора

Добавлено через 15 минут
спасибо за ответы всем. Думаю и так понятно что СТЛ рулит, просто хотелось учтонить. Думаю вопрос закрыт
0
ForEveR
В астрале
Эксперт С++
7973 / 4735 / 321
Регистрация: 24.06.2010
Сообщений: 10,542
Завершенные тесты: 3
05.11.2011, 17:10 #26
AzaKendler, Рулит буст.
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
05.11.2011, 20:33 #27
на самом деле уверенность, что программа с функторами будет работать быстрее, чем с обычными функциями напоминает рассуждения c#'ков о том, что управляемый код может выполняться быстрее нативного
тем не менее все функторы не более чем попытка имитировать работу функций высшего порядка функциональных языков. и попытка не самая удачная
только с лямбдами алгоритмы наконец стали действительно удобными
0
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
05.11.2011, 21:20 #28
Цитата Сообщение от AzaKendler Посмотреть сообщение
если я правильно понял - то что называется редактором связи не вызывается каждый раз при создании объекта? объект создается сам?
Редактор связей(например, std::bind2nd) НЕ вызывается при создании объекта, он сам создаёт объект(например, std::binder2nd), который можно использовать в качестве функтора в функции-алгоритме.
Цитата Сообщение от AzaKendler Посмотреть сообщение
Интересно узнать почему ее работу не надо учитывать?
Потому что она не участвует в том, что происходит внутри функции-алгоритма. Можно даже сделать так
C++
1
2
std::binder2nd< std::greater<int> > more_than_7 = std::bind2nd(std::greater<int>(), 7);
std::find_if(v.begin(), v.end(), more_than_7); // more_than_7 функциональный объект
ничего от этого особо не изменится.
Цитата Сообщение от AzaKendler Посмотреть сообщение
в каждом проходе по элементу вектора работает связка - биндер-конструктор-функтор-деструктор.
Только operator(), который скорее всего будет встроен, т.е. вообще не будет вызываться!(читай про inline функции)
Цитата Сообщение от AzaKendler Посмотреть сообщение
наверно где то я допустил ошибку. и это интересно. посмотри пожалуйста на приложенные выше картинки - от чего зависит сколько раз вызывается конструктор и деструктор временного объекта. или на твой взгляд объект не временный?
Этот вопрос не отсносится к STL вообще, и к обсуждаемой теме в частности. Почитай про то как передаются объекты в функцию.
Цитата Сообщение от AzaKendler Посмотреть сообщение
обладают ли временные объекты из стл "особыми" свойствами?
Я не знаю такого термина, как "временные объекты из стл".

Добавлено через 14 минут
alex_x_x, по поводу вышеприведённых тестов. У меня вариант с использованием функтора на gcc 4.1.2 с ключём -O3 работает в два раза быстрее, чем указатель на функцию(что собственно и не удивительно). Почему у вас получается наоборот для меня загадка. Честно говоря я не особо удивлюсь, если выяснится, что встраивание в приведённых выше тестах, по той или иной причине, вообще не производилось, т.е. вызывался напрямую operator().
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
05.11.2011, 21:25 #29
Цитата Сообщение от rangerx Посмотреть сообщение
У меня вариант с использованием функтора на gcc 4.1.2 с ключём -O3 работает в два раза быстрее, чем указатель на функцию(что собственно и не удивительно)
при чем собственно указатель на функцию
на момент компиляции кода компилятор четко знает какая функция будет передана алгоритму - соответсвенно вполне жестко может ее инлайнить в алгоритм
функтор может выигрывать, только если непосредственно операция сравнения в нем както дико оптимизирована, что маловероятно
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
05.11.2011, 23:01  [ТС] #30
rangerx, прокомментируй пожалуйста тот кусок кода который я вставил. вызовы идут в том порядке о котором я говорим. при сборке из шаблона генерится биндер с нужными типами и далее по списку его класс и далее лесс. при запуске вызыватся биндер, который создает класс, соответственно вызывается конструктор класса. далее ты прав работает только функтор - алгоритм использует оператор ()() для своих нужд в котором вызывается еще и лесс. после того как это отработало, и лесс а затем и оператор ()() вернул фальс, вызвается деструктор класса и алгоритм переходит к следующему элементу вектора. И все повторяется. В дебаге наблюдается именно такая последовательность. Растолкуй непонимающему, каким чудесным образом будет реализовано встраивание, и встраивание чего? биндера? так он в любом случае сгенерит временный объект с оператором()(). Про временные объекты стл - это я так намекал, что неужто если я использую стл - поведение временных объектов будет чем то отличаться? т.е. конструкторы не вызываются, деструкторы тоже.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.11.2011, 23:01
Привет! Вот еще темы с ответами:

Сетевые адаптеры - Сетевое оборудование
В диспетчере появился какой-то левый сетевой адаптер. Кто знает что это такое?

Не работают сетевые адаптеры на пк - Сетевое оборудование
Доброго времени суток форумчане!:) Поставил ОС windows 7 на стационарник и после этого у меня пропала сеть, т.е. вылезла ошибка...

Не работают сетевые адаптеры - Windows 10
Обновился до Win 10 с Win 8.1. Сразу после обновления столкнулся с проблемой: не работают оба сетевых адаптера. В папке Центр...

Адаптеры WI-FI: дальнобойные и с вардрайвингом. - Сетевое оборудование
Какие из адаптеров под USB порекомендуете? Необходим адаптер способный сделать линк на 500-2000метров: 1.Возможность работать с...


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

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

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