]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/regex/performance/table_helper.cpp
1 // Copyright John Maddock 2015.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 # pragma warning (disable : 4224)
10 #include <boost/regex.hpp>
11 #include <boost/lexical_cast.hpp>
12 #include <boost/filesystem.hpp>
13 #include <boost/filesystem/fstream.hpp>
20 std::vector
<std::vector
<double> > data
;
22 inline std::string
sanitize_string(const std::string
& s
)
24 static const boost::regex
e("[^a-zA-Z0-9]+");
25 std::string result
= boost::regex_replace(s
, e
, "_");
26 while(result
[0] == '_')
31 std::string
format_precision(double val
, int digits
)
34 ss
<< std::setprecision(digits
);
40 static std::string content
;
41 boost::filesystem::path path_to_content
;
47 boost::filesystem::path
p(__FILE__
);
50 p
/= "performance_tables.qbk";
52 if(boost::filesystem::exists(p
))
54 boost::filesystem::ifstream
is(p
);
59 char c
= static_cast<char>(is
.get());
68 boost::filesystem::ofstream
os(path_to_content
);
71 void instantiate()const
76 static const content_loader loader
;
78 void load_table(std::vector
<std::vector
<std::string
> >& table
, std::string::const_iterator begin
, std::string::const_iterator end
)
80 static const boost::regex
item_e(
86 boost::regex_token_iterator
<std::string::const_iterator
> i(begin
, end
, item_e
), j
;
91 table
.push_back(std::vector
<std::string
>());
92 boost::regex_token_iterator
<std::string::const_iterator
> k(i
->first
+ 1, i
->second
- 1, item_e
);
96 table
.back().push_back(std::string(k
->first
+ 1, k
->second
- 1));
103 std::string
save_table(std::vector
<std::vector
<std::string
> >& table
)
107 for(std::vector
<std::vector
<std::string
> >::const_iterator i
= table
.begin(), j
= table
.end(); i
!= j
; ++i
)
110 for(std::vector
<std::string
>::const_iterator k
= i
->begin(), l
= i
->end(); k
!= l
; ++k
)
121 void add_to_all_sections(const std::string
& id
, std::string list_name
= "performance_all_sections")
123 std::string::size_type pos
= content
.find("[template " + list_name
+ "[]"), end_pos
;
124 if(pos
== std::string::npos
)
127 // Just append to the end:
129 content
.append("\n[template ").append(list_name
).append("[]\n[").append(id
).append("]\n]\n");
134 // Read in the all list of sections, add our new one (in alphabetical order),
135 // and then rewrite the whole thing:
137 static const boost::regex
item_e(
139 "((?=[^\\]])[^\\[\\]]*+(?0)?+)*+"
142 boost::regex_token_iterator
<std::string::const_iterator
> i(content
.begin() + pos
+ 12 + list_name
.size(), content
.end(), item_e
), j
;
143 std::set
<std::string
> sections
;
148 end_pos
= i
->first
- content
.begin();
151 sections
.insert(std::string(i
->first
+ 1, i
->second
- 1));
155 std::string new_list
= "\n";
156 for(std::set
<std::string
>::const_iterator sec
= sections
.begin(); sec
!= sections
.end(); ++sec
)
158 new_list
+= "[" + *sec
+ "]\n";
160 content
.replace(pos
+ 12 + list_name
.size(), end_pos
- pos
- 12 - list_name
.size(), new_list
);
164 std::string
get_colour(boost::uintmax_t val
, boost::uintmax_t best
)
166 if(val
<= best
* 1.2)
173 boost::intmax_t get_value_from_cell(const std::string
& cell
)
175 static const boost::regex
time_e("(\\d+)ns");
177 if(regex_search(cell
, what
, time_e
))
179 return boost::lexical_cast
<boost::uintmax_t>(what
.str(1));
184 void add_cell(boost::intmax_t val
, const std::string
& table_name
, const std::string
& row_name
, const std::string
& column_heading
)
187 // Load the table, add our data, and re-write:
189 std::string table_id
= "table_" + sanitize_string(table_name
);
190 boost::regex
table_e("\\[table:" + table_id
191 + "\\s(?:[^\\[]|\\\\.)++"
193 "((?:[^\\[\\]]|\\\\.)*+(?2)?+)*+"
198 boost::smatch table_location
;
199 if(regex_search(content
, table_location
, table_e
))
201 std::vector
<std::vector
<std::string
> > table_data
;
202 load_table(table_data
, table_location
[1].first
, table_location
[1].second
);
204 // Figure out which column we're on:
206 unsigned column_id
= 1001u;
207 for(unsigned i
= 0; i
< table_data
[0].size(); ++i
)
209 if(table_data
[0][i
] == column_heading
)
218 // Need a new column, must be adding a new compiler to the table!
220 table_data
[0].push_back(column_heading
);
221 for(unsigned i
= 1; i
< table_data
.size(); ++i
)
222 table_data
[i
].push_back(std::string());
223 column_id
= table_data
[0].size() - 1;
226 // Figure out the row:
228 unsigned row_id
= 1001;
229 for(unsigned i
= 1; i
< table_data
.size(); ++i
)
231 if(table_data
[i
][0] == row_name
)
240 // Need a new row, add it now:
242 table_data
.push_back(std::vector
<std::string
>());
243 table_data
.back().push_back(row_name
);
244 for(unsigned i
= 1; i
< table_data
[0].size(); ++i
)
245 table_data
.back().push_back(std::string());
246 row_id
= table_data
.size() - 1;
249 // Find the best result in this row:
251 boost::uintmax_t best
= (std::numeric_limits
<boost::uintmax_t>::max
)();
252 std::vector
<boost::intmax_t> values
;
253 for(unsigned i
= 1; i
< table_data
[row_id
].size(); ++i
)
259 values
.push_back(val
);
263 std::cout
<< "Existing cell value was " << table_data
[row_id
][i
] << std::endl
;
264 boost::uintmax_t cell_val
= get_value_from_cell(table_data
[row_id
][i
]);
265 std::cout
<< "Extracted value: " << cell_val
<< std::endl
;
268 values
.push_back(cell_val
);
274 for(unsigned i
= 1; i
< table_data
[row_id
].size(); ++i
)
276 std::string
& s
= table_data
[row_id
][i
];
278 if(values
[i
- 1] < 0)
284 s
+= get_colour(values
[i
- 1], best
);
286 s
+= format_precision(static_cast<double>(values
[i
- 1]) / best
, 2);
288 s
+= boost::lexical_cast
<std::string
>(values
[i
- 1]) + "ns)]";
292 // Convert back to a string and insert into content:
293 std::sort(table_data
.begin() + 1, table_data
.end(), [](std::vector
<std::string
> const& a
, std::vector
<std::string
> const& b
) { return a
[0] < b
[0]; } );
294 std::string c
= save_table(table_data
);
295 content
.replace(table_location
.position(1), table_location
.length(1), c
);
300 // Create a new table and try again:
302 std::string new_table
= "\n[template " + table_id
;
303 new_table
+= "[]\n[table:" + table_id
;
305 new_table
+= table_name
;
306 new_table
+= "\n[[Expression[br]Text][";
307 new_table
+= column_heading
;
310 new_table
+= row_name
;
311 new_table
+= "][[role blue 1.00[br](";
312 new_table
+= boost::lexical_cast
<std::string
>(val
);
313 new_table
+= "ns)]]]\n]\n]\n";
315 std::string::size_type pos
= content
.find("[/tables:]");
316 if(pos
!= std::string::npos
)
317 content
.insert(pos
+ 10, new_table
);
319 content
+= "\n\n[/tables:]\n" + new_table
;
321 // Add a section for this table as well:
323 std::string section_id
= "section_" + sanitize_string(table_name
);
324 if(content
.find(section_id
+ "[]") == std::string::npos
)
326 std::string new_section
= "\n[template " + section_id
+ "[]\n[section:" + section_id
+ " " + table_name
+ "]\n[" + table_id
+ "]\n[endsect]\n]\n";
327 pos
= content
.find("[/sections:]");
328 if(pos
!= std::string::npos
)
329 content
.insert(pos
+ 12, new_section
);
331 content
+= "\n\n[/sections:]\n" + new_section
;
332 add_to_all_sections(section_id
);
335 // Add to list of all tables (not in sections):
337 add_to_all_sections(table_id
, "performance_all_tables");
341 void report_execution_time(double t
, std::string table
, std::string row
, std::string heading
)
344 add_cell(static_cast<boost::uintmax_t>(t
/ 1e-9), table
, row
, heading
);
346 catch(const std::exception
& e
)
348 std::cout
<< "Error in adding cell: " << e
.what() << std::endl
;
353 std::string
boost_name()
355 return "boost " + boost::lexical_cast
<std::string
>(BOOST_VERSION
/ 100000) + "." + boost::lexical_cast
<std::string
>((BOOST_VERSION
/ 100) % 1000);
358 std::string
compiler_name()
361 return COMPILER_NAME
;
363 return BOOST_COMPILER
;
367 std::string
platform_name()
370 return "Windows x64";
372 return BOOST_PLATFORM
;
377 std::string
get_compiler_options_name()
379 #if defined(BOOST_MSVC) || defined(__ICL)
388 result
+= "/arch:AVX /Ox";
392 result
+= " (x64 build)";
396 #elif defined(__AVX2__)
397 result
+= "/arch:AVX2 /Ox";
398 #elif defined(__AVX__)
399 result
+= "/arch:AVX /Ox";
400 #elif _M_IX86_FP == 2
401 result
+= "/arch:sse2 /Ox";
403 result
+= "/arch:ia32 /Ox";
405 result
+= " (x86 build)";
407 std::cout
<< "Compiler options are found as: " << result
<< std::endl
;