]>
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>
14 #include <boost/container_hash/hash.hpp>
21 std::vector
<std::vector
<double> > data
;
23 inline std::string
sanitize_string(const std::string
& s
)
25 static const boost::regex
e("[^a-zA-Z0-9]+");
26 std::string result
= boost::regex_replace(s
, e
, "_");
27 while(result
[0] == '_')
32 inline std::string
sanitize_short_string(const std::string
& s
)
34 unsigned id
= boost::hash
<std::string
>()(s
);
35 return sanitize_string("id" + boost::lexical_cast
<std::string
>(id
));
38 std::string
format_precision(double val
, int digits
)
41 ss
<< std::setprecision(digits
);
47 static std::string content
;
48 boost::filesystem::path path_to_content
;
54 boost::filesystem::path
p(__FILE__
);
57 p
/= "performance_tables.qbk";
59 if(boost::filesystem::exists(p
))
61 boost::filesystem::ifstream
is(p
);
66 char c
= static_cast<char>(is
.get());
75 boost::filesystem::ofstream
os(path_to_content
);
78 void instantiate()const
83 static const content_loader loader
;
85 void load_table(std::vector
<std::vector
<std::string
> >& table
, std::string::const_iterator begin
, std::string::const_iterator end
)
87 static const boost::regex
item_e(
93 boost::regex_token_iterator
<std::string::const_iterator
> i(begin
, end
, item_e
), j
;
98 table
.push_back(std::vector
<std::string
>());
99 boost::regex_token_iterator
<std::string::const_iterator
> k(i
->first
+ 1, i
->second
- 1, item_e
);
103 table
.back().push_back(std::string(k
->first
+ 1, k
->second
- 1));
110 std::string
save_table(std::vector
<std::vector
<std::string
> >& table
)
114 for(std::vector
<std::vector
<std::string
> >::const_iterator i
= table
.begin(), j
= table
.end(); i
!= j
; ++i
)
117 for(std::vector
<std::string
>::const_iterator k
= i
->begin(), l
= i
->end(); k
!= l
; ++k
)
128 void add_to_all_sections(const std::string
& id
, std::string list_name
= "performance_all_sections")
130 std::string::size_type pos
= content
.find("[template " + list_name
+ "[]"), end_pos
;
131 if(pos
== std::string::npos
)
134 // Just append to the end:
136 content
.append("\n[template ").append(list_name
).append("[]\n[").append(id
).append("]\n]\n");
141 // Read in the all list of sections, add our new one (in alphabetical order),
142 // and then rewrite the whole thing:
144 static const boost::regex
item_e(
146 "((?=[^\\]])[^\\[\\]]*+(?0)?+)*+"
149 boost::regex_token_iterator
<std::string::const_iterator
> i(content
.begin() + pos
+ 12 + list_name
.size(), content
.end(), item_e
), j
;
150 std::set
<std::string
> sections
;
155 end_pos
= i
->first
- content
.begin();
158 sections
.insert(std::string(i
->first
+ 1, i
->second
- 1));
162 std::string new_list
= "\n";
163 for(std::set
<std::string
>::const_iterator sec
= sections
.begin(); sec
!= sections
.end(); ++sec
)
165 new_list
+= "[" + *sec
+ "]\n";
167 content
.replace(pos
+ 12 + list_name
.size(), end_pos
- pos
- 12 - list_name
.size(), new_list
);
171 std::string
get_colour(boost::uintmax_t val
, boost::uintmax_t best
)
173 if(val
<= best
* 1.2)
180 boost::intmax_t get_value_from_cell(const std::string
& cell
)
182 static const boost::regex
time_e("(\\d+)ns");
184 if(regex_search(cell
, what
, time_e
))
186 return boost::lexical_cast
<boost::uintmax_t>(what
.str(1));
191 void add_cell(boost::intmax_t val
, const std::string
& table_name
, const std::string
& row_name
, const std::string
& column_heading
)
194 // Load the table, add our data, and re-write:
196 std::string table_id
= "table_" + sanitize_string(table_name
);
197 boost::regex
table_e("\\[table:" + table_id
198 + "\\s(?:[^\\[]|\\\\.)++"
200 "((?:[^\\[\\]]|\\\\.)*+(?2)?+)*+"
205 boost::smatch table_location
;
206 if(regex_search(content
, table_location
, table_e
))
208 std::vector
<std::vector
<std::string
> > table_data
;
209 load_table(table_data
, table_location
[1].first
, table_location
[1].second
);
211 // Figure out which column we're on:
213 unsigned column_id
= 1001u;
214 for(unsigned i
= 0; i
< table_data
[0].size(); ++i
)
216 if(table_data
[0][i
] == column_heading
)
225 // Need a new column, must be adding a new compiler to the table!
227 table_data
[0].push_back(column_heading
);
228 for(unsigned i
= 1; i
< table_data
.size(); ++i
)
229 table_data
[i
].push_back(std::string());
230 column_id
= table_data
[0].size() - 1;
233 // Figure out the row:
235 unsigned row_id
= 1001;
236 for(unsigned i
= 1; i
< table_data
.size(); ++i
)
238 if(table_data
[i
][0] == row_name
)
247 // Need a new row, add it now:
249 table_data
.push_back(std::vector
<std::string
>());
250 table_data
.back().push_back(row_name
);
251 for(unsigned i
= 1; i
< table_data
[0].size(); ++i
)
252 table_data
.back().push_back(std::string());
253 row_id
= table_data
.size() - 1;
256 // Find the best result in this row:
258 boost::uintmax_t best
= (std::numeric_limits
<boost::uintmax_t>::max
)();
259 std::vector
<boost::intmax_t> values
;
260 for(unsigned i
= 1; i
< table_data
[row_id
].size(); ++i
)
266 values
.push_back(val
);
270 std::cout
<< "Existing cell value was " << table_data
[row_id
][i
] << std::endl
;
271 boost::uintmax_t cell_val
= get_value_from_cell(table_data
[row_id
][i
]);
272 std::cout
<< "Extracted value: " << cell_val
<< std::endl
;
275 values
.push_back(cell_val
);
281 for(unsigned i
= 1; i
< table_data
[row_id
].size(); ++i
)
283 std::string
& s
= table_data
[row_id
][i
];
285 if(values
[i
- 1] < 0)
291 s
+= get_colour(values
[i
- 1], best
);
293 s
+= format_precision(static_cast<double>(values
[i
- 1]) / best
, 2);
295 s
+= boost::lexical_cast
<std::string
>(values
[i
- 1]) + "ns)]";
299 // Convert back to a string and insert into content:
300 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]; } );
301 std::string c
= save_table(table_data
);
302 content
.replace(table_location
.position(1), table_location
.length(1), c
);
307 // Create a new table and try again:
309 std::string new_table
= "\n[template " + table_id
;
310 new_table
+= "[]\n[table:" + table_id
;
312 new_table
+= table_name
;
313 new_table
+= "\n[[Expression[br]Text][";
314 new_table
+= column_heading
;
317 new_table
+= row_name
;
318 new_table
+= "][[role blue 1.00[br](";
319 new_table
+= boost::lexical_cast
<std::string
>(val
);
320 new_table
+= "ns)]]]\n]\n]\n";
322 std::string::size_type pos
= content
.find("[/tables:]");
323 if(pos
!= std::string::npos
)
324 content
.insert(pos
+ 10, new_table
);
326 content
+= "\n\n[/tables:]\n" + new_table
;
328 // Add a section for this table as well:
330 std::string section_id
= "section_" + sanitize_short_string(table_name
);
331 if(content
.find(section_id
+ "[]") == std::string::npos
)
333 std::string new_section
= "\n[template " + section_id
+ "[]\n[section:" + section_id
+ " " + table_name
+ "]\n[" + table_id
+ "]\n[endsect]\n]\n";
334 pos
= content
.find("[/sections:]");
335 if(pos
!= std::string::npos
)
336 content
.insert(pos
+ 12, new_section
);
338 content
+= "\n\n[/sections:]\n" + new_section
;
339 add_to_all_sections(section_id
);
342 // Add to list of all tables (not in sections):
344 add_to_all_sections(table_id
, "performance_all_tables");
348 void report_execution_time(double t
, std::string table
, std::string row
, std::string heading
)
351 add_cell(static_cast<boost::uintmax_t>(t
/ 1e-9), table
, row
, heading
);
353 catch(const std::exception
& e
)
355 std::cout
<< "Error in adding cell: " << e
.what() << std::endl
;
360 std::string
boost_name()
362 return "boost " + boost::lexical_cast
<std::string
>(BOOST_VERSION
/ 100000) + "." + boost::lexical_cast
<std::string
>((BOOST_VERSION
/ 100) % 1000);
365 std::string
compiler_name()
368 return COMPILER_NAME
;
370 return BOOST_COMPILER
;
374 std::string
platform_name()
377 return "Windows x64";
379 return BOOST_PLATFORM
;
384 std::string
get_compiler_options_name()
386 #if defined(BOOST_MSVC) || defined(__ICL)
395 result
+= "/arch:AVX /Ox";
399 result
+= " (x64 build)";
403 #elif defined(__AVX2__)
404 result
+= "/arch:AVX2 /Ox";
405 #elif defined(__AVX__)
406 result
+= "/arch:AVX /Ox";
407 #elif _M_IX86_FP == 2
408 result
+= "/arch:sse2 /Ox";
410 result
+= "/arch:ia32 /Ox";
412 result
+= " (x86 build)";
414 std::cout
<< "Compiler options are found as: " << result
<< std::endl
;