Ответ 1
Проблема заключается в использовании вами функции std::. Вы отправляете его копией и, следовательно, копируете его содержимое (и выполняете это рекурсивно, когда вы разматываете параметры).
Теперь, для указателя на функцию, содержимое, ну, просто указатель на функцию. Для лямбда содержимое - это, по крайней мере, указатель на функцию + ссылку, которую вы захватили. Это в два раза больше для копирования. Кроме того, из-за копирования стирания std:: function любые данные будут, скорее всего, более медленными (не встроенными).
Здесь есть несколько вариантов, и лучше всего, вероятно, будет передавать не std:: function, а шаблон вместо этого. Преимущества в том, что ваш вызов метода с большей вероятностью будет встроен, никакое стирание типа не происходит с помощью std:: function, никакого копирования не происходит, все очень хорошо. Например:
template <typename TFunc>
void ProcessArguments(const TFunc& process)
{}
template <typename TFunc, typename HEAD, typename ... TAIL>
void ProcessArguments(const TFunc& process, const HEAD &head, const TAIL &... tail)
{
process(head);
ProcessArguments(process, tail...);
}
Второй вариант делает то же самое, но отправляет process
по копии. Теперь копирование действительно происходит, но все еще аккуратно включено.
Не менее важно то, что тело process
'также может быть встроено, особенно для lamda. В зависимости от сложности копирования лямбда-объекта и его размера, передача копией может быть или не быть быстрее, чем передача по ссылке. Это может быть быстрее, потому что у компилятора может быть сложнее рассуждать о ссылке, чем локальная копия.
template <typename TFunc>
void ProcessArguments(TFunc process)
{}
template <typename TFunc, typename HEAD, typename ... TAIL>
void ProcessArguments(TFunc process, const HEAD &head, const TAIL &... tail)
{
process(head);
ProcessArguments(process, tail...);
}
Третий вариант, ну, попробуйте передать std:: function < > по ссылке. Таким образом, вы, по крайней мере, избегаете копирования, но вызовы не будут включены.
Вот некоторые первичные результаты (с использованием компилятора ideones 'С++ 11). Обратите внимание, что, как и ожидалось, встроенное тело лямбда дает вам лучшую производительность:
Original function:
0.483035s
Original lambda:
1.94531s
Function via template copy:
0.094748
### Lambda via template copy:
0.0264867s
Function via template reference:
0.0892594s
### Lambda via template reference:
0.0264201s
Function via std::function reference:
0.0891776s
Lambda via std::function reference:
0.09s