【问题标题】:how to do performance test using the boost library for a custom library如何使用自定义库的 boost 库进行性能测试
【发布时间】:2014-06-27 14:11:58
【问题描述】:

我需要对用 c++ 编写的库进行性能测试。该库由几组结构组成。我已经对这些类进行了序列化测试,但不确定如何对这些类进行性能测试。下面是库中的结构示例

struct X
{
   public:
      int p;
      double q;

      X();
     ~X();
}

struct Y
{
    float m;
    double n;

     Y();
    ~Y();
}

struct Z
{
public:
   std::map<std::string,boost::shared_ptr<X>> Xtype;
   std::map<std::string,boost::shared_ptr<Y>> Ytype; 

   int i;
   string name; 

   Z();
  ~Z();

}

如果提供任何示例,那将是非常好的。

【问题讨论】:

  • 使用profiler
  • @CaptainObvlious - 只需要在单元测试中使用 boost
  • 这甚至不是一句话,@user3295725。为什么突然提到单元测试?
  • @sehe -- 抱歉,我误提了它..它应该只是测试..

标签: c++ serialization boost performance-testing boost-serialization


【解决方案1】:

好的,所以我在类型中添加了序列化(你为什么忽略它?)

struct X
{
    int p;
    double q;
  private: 
    friend boost::serialization::access;
    template <typename Ar>
        void serialize(Ar& ar, unsigned) {
            ar & BOOST_SERIALIZATION_NVP(p);
            ar & BOOST_SERIALIZATION_NVP(q);
        }
};

struct Y
{
    float m;
    double n;
  private: 
    friend boost::serialization::access;
    template <typename Ar>
        void serialize(Ar& ar, unsigned) {
            ar & BOOST_SERIALIZATION_NVP(m);
            ar & BOOST_SERIALIZATION_NVP(n);
        }
};

struct Z
{
   std::map<std::string, boost::shared_ptr<X>> Xtype;
   std::map<std::string, boost::shared_ptr<Y>> Ytype; 

   int i;
   std::string name; 
  private: 
    friend boost::serialization::access;
    template <typename Ar>
        void serialize(Ar& ar, unsigned) {
            ar & BOOST_SERIALIZATION_NVP(i);
            ar & BOOST_SERIALIZATION_NVP(name);
            ar & BOOST_SERIALIZATION_NVP(Xtype);
            ar & BOOST_SERIALIZATION_NVP(Ytype);
        }
};

现在,使用the Nonius benchmarking mini-framework,编写以下基准:

Z const& fixture(); // forward

#include <nonius/main.h++>
#include <sstream>

NONIUS_BENCHMARK("text archive", [](nonius::chronometer meter) {
    auto const& z = fixture();
    meter.measure([&](int /*i*/) { 
        std::stringstream ss;
        boost::archive::text_oarchive oa(ss);
        oa << z;

        Z clone;
        boost::archive::text_iarchive ia(ss);
        ia >> clone;

        return ss.str().size(); // something observable to thwart the overly smart optimizer
    });
})

NONIUS_BENCHMARK("binary archive", [](nonius::chronometer meter) {
    auto const& z = fixture();
    meter.measure([&](int /*i*/) { 
        std::stringstream ss;
        boost::archive::binary_oarchive oa(ss);
        oa << z;

        Z clone;
        boost::archive::binary_iarchive ia(ss);
        ia >> clone;

        return ss.str().size(); // something observable to thwart the overly smart optimizer
    });
})

NONIUS_BENCHMARK("xml archive", [](nonius::chronometer meter) {
    auto const& z = fixture();
    meter.measure([&](int /*i*/) { 
        std::stringstream ss;
        boost::archive::xml_oarchive oa(ss);
        oa << boost::serialization::make_nvp("root", z);

        Z clone;
        boost::archive::xml_iarchive ia(ss);
        ia >> boost::serialization::make_nvp("root", clone);

        return ss.str().size(); // something observable to thwart the overly smart optimizer
    });
})

原始输出是(对于 1000 个随机 X 和 3000 个随机 Y 值的夹具):

text archive
mean: 236.069 μs
std dev: 2.54923 μs
variance is unaffected by outliers

binary archive
mean: 92.9736 μs
std dev: 3.35504 μs
variance is moderately inflated by outliers

xml archive
mean: 786.746 μs
std dev: 4.676 μs
variance is unaffected by outliers

互动剧情:click here


测试夹具其实要多很多工作,定义如下:

#include <boost/random.hpp> // for test data
#include <boost/bind.hpp>
#include <boost/make_shared.hpp>
#include <algorithm>

Z const& fixture()
{
    static Z const z = [] {
        Z z;

        boost::random::mt19937 engine;
        auto fgen = boost::bind(boost::random::uniform_real_distribution<float>(), engine);
        auto dgen = boost::bind(boost::random::uniform_real_distribution<double>(), engine);
        auto cgen = boost::bind(boost::random::uniform_int_distribution<char>('a', 'z'), engine);
        auto igen = boost::bind(boost::random::uniform_int_distribution<int>(), engine);

        auto sgen = [&] (int maxlen) { std::string s; std::generate_n(back_inserter(s), igen() % maxlen, cgen); return s; };

        std::generate_n(inserter(z.Ytype, z.Ytype.end()), 1000, [&] { 
                auto py = boost::make_shared<Y>(); 
                py->m = fgen();
                py->n = dgen();
                return std::make_pair(sgen(32), py);
                });
        std::generate_n(inserter(z.Xtype, z.Xtype.end()), 3000, [&] { 
                auto px = boost::make_shared<X>(); 
                px->p = igen();
                px->q = dgen();
                return std::make_pair(sgen(32), px);
                });

        z.i    = igen();
        z.name = sgen(8);

        return z; 
    }();
    return z;
}

完整代码清单

开启Coliru

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2011-03-03
    相关资源
    最近更新 更多