6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
15 #include <boost/regex.hpp>
16 #include <boost/tuple/tuple.hpp>
17 #include <boost/lexical_cast.hpp>
18 #include <boost/foreach.hpp>
19 #include <boost/format.hpp>
20 #include <boost/multi_index_container.hpp>
21 #include <boost/multi_index/hashed_index.hpp>
22 #include <boost/multi_index/sequenced_index.hpp>
24 boost::regex
generator_regex("(?:fixed-range )?([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
25 boost::regex
distribution_regex("([^\\s]+)( virtual function)? ([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
27 std::string
template_name(std::string arg
) {
28 return boost::regex_replace(arg
, boost::regex("[^\\w]"), "_");
31 struct compare_second
{
33 bool operator()(const Pair
& p1
, const Pair
& p2
) const {
34 return (p1
.second
< p2
.second
);
38 typedef boost::multi_index_container
<
41 boost::multi_index::sequenced
<>,
42 boost::multi_index::hashed_unique
<boost::multi_index::identity
<std::string
> >
46 int main(int argc
, char** argv
) {
51 if(argc
>= 2 && std::strcmp(argv
[1], "-linux") == 0) {
59 std::vector
<std::pair
<std::string
, double> > generator_info
;
61 while(std::getline(std::cin
, line
)) {
63 if(std::strncmp(line
.c_str(), "counting ", 9) == 0) break;
64 if(boost::regex_match(line
, match
, generator_regex
)) {
65 std::string
generator(match
[1]);
66 double time
= boost::lexical_cast
<double>(match
[2]);
67 if(generator
!= "counting") {
68 generator_info
.push_back(std::make_pair(generator
, time
));
71 std::cerr
<< "oops: " << line
<< std::endl
;
75 double min
= std::min_element(generator_info
.begin(), generator_info
.end(), compare_second())->second
;
77 std::ofstream
generator_defs("performance_data.qbk");
78 std::ofstream
generator_performance(("generator_performance_" + suffix
+ ".qbk").c_str());
79 generator_performance
<< "[table Basic Generators (" << id
<< ")\n";
80 generator_performance
<< " [[generator] [M rn/sec] [time per random number \\[nsec\\]] "
81 "[relative speed compared to fastest \\[percent\\]]]\n";
83 typedef std::pair
<std::string
, double> pair_type
;
84 BOOST_FOREACH(const pair_type
& pair
, generator_info
) {
85 generator_defs
<< boost::format("[template %s_speed[] %d%%]\n")
86 % template_name(pair
.first
) % static_cast<int>(100*min
/pair
.second
);
87 generator_performance
<< boost::format(" [[%s][%g][%g][%d%%]]\n")
88 % pair
.first
% (1000/pair
.second
) % pair
.second
% static_cast<int>(100*min
/pair
.second
);
90 generator_performance
<< "]\n";
92 std::map
<std::pair
<std::string
, std::string
>, double> distribution_info
;
93 unique_list generator_names
;
94 unique_list distribution_names
;
97 if(boost::regex_match(line
, match
, distribution_regex
)) {
98 if(!match
[2].matched
&& match
[1] != "counting") {
99 std::string
generator(match
[1]);
100 std::string
distribution(match
[3]);
101 double time
= boost::lexical_cast
<double>(match
[4]);
102 generator_names
.push_back(generator
);
103 distribution_names
.push_back(distribution
);
104 distribution_info
.insert(std::make_pair(std::make_pair(distribution
, generator
), time
));
107 std::cerr
<< "oops: " << line
<< std::endl
;
109 } while(std::getline(std::cin
, line
));
111 std::ofstream
distribution_performance(("distribution_performance_" + suffix
+ ".qbk").c_str());
113 distribution_performance
<< "[table Distributions (" << id
<< ")\n";
114 distribution_performance
<< " [[\\[M rn/sec\\]]";
115 BOOST_FOREACH(const std::string
& generator
, generator_names
) {
116 distribution_performance
<< boost::format("[%s]") % generator
;
118 distribution_performance
<< "]\n";
119 BOOST_FOREACH(const std::string
& distribution
, distribution_names
) {
120 distribution_performance
<< boost::format(" [[%s]") % distribution
;
121 BOOST_FOREACH(const std::string
& generator
, generator_names
) {
122 std::map
<std::pair
<std::string
, std::string
>, double>::iterator pos
=
123 distribution_info
.find(std::make_pair(distribution
, generator
));
124 if(pos
!= distribution_info
.end()) {
125 distribution_performance
<< boost::format("[%g]") % (1000/pos
->second
);
127 distribution_performance
<< "[-]";
130 distribution_performance
<< "]\n";
132 distribution_performance
<< "]\n";