Я пытаюсь отменить, если временные накладные расходы, введенные boost::function для оценки математических функций, неоценимы по сравнению с использованием function templates
.llvm g ++ и boost function
Код для теста, который я использую, приведен ниже.
С g++
традиционными французским, накладным расходами с boost::function
является negligeable:
$ g++ -O3 main.cxx
$ ./a.out
METHOD INTEGRAL TIME TO COMPUTE (SEC)
Direct 0.379885 3.360000
Function template 0.379885 3.380000
Boost function 0.379885 3.400000
С llvm-g++
, есть прирост скорости в 1,5 раза для templates function
, но не для усиления boost::function
.
$ llvm-g++ -O3 main.cxx
METHOD INTEGRAL TIME TO COMPUTE (SEC)
Direct 0.379885 2.170000
Function template 0.379885 2.160000
Boost function 0.379885 3.360000
Можно ли получить 1,5 усиления для boost::function
и llvm-g++
?
#include <boost/function.hpp>
#include <math.h>
#include <stdio.h>
typedef unsigned int UInt;
using namespace std;
//=============================================================================
// chrono
//=============================================================================
class Chrono
{
clock_t t1_,t2_,dt_;
public:
Chrono(){}
void start() { t1_=clock(); };
void stop() { t2_=clock(); };
double diff() { return ((double)(t2_ - t1_))/CLOCKS_PER_SEC; };
};
//=============================================================================
// function to integrate
//=============================================================================
inline double fct(double x)
{
return 1./(1.+exp(x));
}
//=============================================================================
// using direct method
//=============================================================================
double direct(double a, double b, UInt numSamplePoints)
{
double delta = (b-a)/(numSamplePoints-1);
double sum = 0.;
for (UInt i=0; i < numSamplePoints-1; ++i)
sum += 1./(1. + exp(a + i*delta));
return sum * delta;
}
//=============================================================================
// using function template
//=============================================================================
template<double functionToIntegrate(double)>
double integrate(double a, double b, UInt numSamplePoints)
{
double delta = (b-a)/(numSamplePoints-1);
double sum = 0.;
for (UInt i=0; i < numSamplePoints-1; ++i)
sum += functionToIntegrate(a + i*delta);
return sum * delta;
}
//=============================================================================
// using Boost function
//=============================================================================
typedef boost::function<double (double)> fct_type;
class IntegratorBoost {
public:
fct_type functionToIntegrate;
IntegratorBoost(fct_type fct): functionToIntegrate(fct){}
double integrate(double a, double b, UInt numSamplePoints)
{
double delta = (b-a)/(numSamplePoints-1);
double sum = 0.;
for (UInt i=0; i < numSamplePoints-1; ++i)
sum += functionToIntegrate(a + i*delta);
return sum * (b-a)/numSamplePoints;
}
};
//=============================================================================
// main
//=============================================================================
int main()
{
double integral;
UInt numSamplePoints = 5E07;
Chrono chrono;
printf("%-20s%-10s%-30s\n","METHOD","INTEGRAL","TIME TO COMPUTE (SEC)");
// Direct
chrono.start();
integral = direct(0., 1., numSamplePoints);
chrono.stop();
printf("%-20s%-10f%-30f\n","Direct",integral,chrono.diff());
// Function template
chrono.start();
integral = integrate<fct>(0., 1.,numSamplePoints);
chrono.stop();
printf("%-20s%-10f%-30f\n","Function template",integral,chrono.diff());
// Boost function
chrono.start();
IntegratorBoost intboost(fct);
integral = intboost.integrate(0.,1.,numSamplePoints);
chrono.stop();
printf("%-20s%-10f%-30f\n","Boost function",integral,chrono.diff());
}
Использование 'clock' для эталонных тестов не так уж и надежно. Я подозреваю, что это может исказить ваши результаты, чтобы сделать их бессмысленными. –
В Linux я бы рекомендовал 'gettimeofday' для более точного таймера. Кроме того, llvm-g ++ устарел (и был основан на g ++ 4.2), я бы рекомендовал переключиться на Clang 3.0 для лучшего соответствия и нового и блестящего C++ 11. –
У меня также есть функция лямбда, чтобы увидеть, как она складывается. Он обладает всеми преимуществами функции boost :: function и более низкого уровня. – StilesCrisis