読者です 読者をやめる 読者になる 読者になる

ボレロ村上 - ENiyGmaA Code

中3女子です。

boost::call_traitsを使った最適化 その2

ベンチをとってみた。

Visual C++ 2008 Express SP1
構成:Release (最適化=実行速度(/O2))
Windows XP SP3
3.00GHz、3.25GB RAM

    • CallTraitsTest.cpp
#pragma warning(disable : 4819)

#include <cstdio>
#include <iostream>
#include <boost/array.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/utility/enable_if.hpp>
#include <sprig/type_traits/is_call_reference_param.hpp>
#include <sprig/performance_timer.hpp>

// do_something
template<typename T>
void do_something(T const& v) {
    boost::array<T, 100> arr;
    BOOST_FOREACH(T& e, arr) {
        e = v;
    }
}

// do_something2
template<typename T>
typename boost::enable_if<
    sprig::is_call_reference_param<T>
>::type do_something2(T const& v) {
    boost::array<T, 100> arr;
    BOOST_FOREACH(T& e, arr) {
        e = v;
    }
}
template<typename T>
typename boost::disable_if<
    sprig::is_call_reference_param<T>
>::type do_something2(T const v) {
    boost::array<T, 100> arr;
    BOOST_FOREACH(T& e, arr) {
        e = v;
    }
}

struct heavy_t {
    int i[100];
};

int main() {
    int const light = 100;
    heavy_t const heavy = { 0 };
    std::size_t const count = 100000000;
    std::size_t const count2 = 1000000;
    sprig::performance_timer timer;
    {
        std::cout << "light:" << std::endl;
        timer.restart();
        for (std::size_t i = 0, last = count; i != last; ++i) {
            do_something(light);
        }
        double elapsed = timer.elapsed();
        timer.restart();
        for (std::size_t i = 0, last = count; i != last; ++i) {
            do_something2(light);
        }
        double elapsed2 = timer.elapsed();
        std::cout << boost::format("do_something : elapsed=%f[s]") % elapsed << std::endl;
        std::cout << boost::format("do_something2: elapsed=%f[s]") % elapsed2 << std::endl;
        std::cout << boost::format("rating=%f") % (elapsed2 / elapsed) << std::endl;
    }
    {
        std::cout << "heavy:" << std::endl;
        timer.restart();
        for (std::size_t i = 0, last = count2; i != last; ++i) {
            do_something(heavy);
        }
        double elapsed = timer.elapsed();
        timer.restart();
        for (std::size_t i = 0, last = count2; i != last; ++i) {
            do_something2(heavy);
        }
        double elapsed2 = timer.elapsed();
        std::cout << boost::format("do_something : elapsed=%f[s]") % elapsed << std::endl;
        std::cout << boost::format("do_something2: elapsed=%f[s]") % elapsed2 << std::endl;
        std::cout << boost::format("rating=%f") % (elapsed2 / elapsed) << std::endl;
    }
    ::getchar();
    return 0;
}


何回か試してみて、毎回ほぼ同じ結果。
const参照渡しと値渡しで分けた場合、1.2% ほど高速だった。