mercredi 20 avril 2011

Performances: lambda vs boost::bind

Maintenant que l'on a les lambdas, peut-on se passer de boost::bind? Et qui est le plus rapide?

Voici un petit programme qui fait tourner un certain nombre de "tâches" de manière asynchrone à travers le framework asio, en passant un handler soit via un (une?) lambda, soit un boost::bind.


#include <iostream>
#include <chrono>

#include <boost/asio.hpp>
#include <boost/bind.hpp>


class Recursive
{
public:
Recursive(boost::asio::io_service & io_service,
bool lambda,
int max):
m_io_service(io_service),
m_lambda(lambda),
m_max(max)
{
}

void run(int i)
{
if(i < m_max)
{
if(m_lambda)
{
m_io_service.post([this, i](){run(i + 1);});
}
else
{
m_io_service.post(boost::bind(&Recursive::run,
this,
i + 1));
}
}
}

private:
boost::asio::io_service & m_io_service;
bool m_lambda;
int m_max;
};

int main()
{
{
boost::asio::io_service io_service;
Recursive rec(io_service, true, 10000000);
io_service.post([&rec](){rec.run(0);});

auto t1 = std::chrono::system_clock::now();

io_service.run();

auto t2 = std::chrono::system_clock::now();
std::cout << "lambda: " << (t2 - t1).count() << std::endl;
}

{
boost::asio::io_service io_service;
Recursive rec(io_service, false, 10000000);
io_service.post([&rec](){rec.run(0);});

auto t1 = std::chrono::system_clock::now();

io_service.run();

auto t2 = std::chrono::system_clock::now();
std::cout << "bind: " << (t2 - t1).count() << std::endl;
}
}


Eh bien, les braves petites lambdas sont significativement plus rapides que boost::bind, d'environ 5 à 6 %. Il ne s'agit pas d'allocations, valgrind confirmant que les allocations mémoire restent les mêmes. Peut-être le foncteur correspondant à un boost::bind est-il plus compliqué à construire.

Aucun commentaire: