+ make benchmark tests copyable and avoid sharing state between threads
+ add polygon_clipper test
This commit is contained in:
parent
50b8386dd8
commit
1521817378
1 changed files with 99 additions and 26 deletions
|
@ -18,7 +18,6 @@
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/function.hpp>
|
|
||||||
|
|
||||||
#define BOOST_CHRONO_HEADER_ONLY
|
#define BOOST_CHRONO_HEADER_ONLY
|
||||||
#include <boost/chrono/process_cpu_clocks.hpp>
|
#include <boost/chrono/process_cpu_clocks.hpp>
|
||||||
|
@ -40,32 +39,40 @@ void benchmark(T & test_runner, std::string const& name)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
bool should_run_test = true;
|
bool should_run_test = true;
|
||||||
if (!test_set.empty()) {
|
if (!test_set.empty())
|
||||||
|
{
|
||||||
should_run_test = test_set.find(test_num) != test_set.end();
|
should_run_test = test_set.find(test_num) != test_set.end();
|
||||||
}
|
}
|
||||||
if (should_run_test || dry_run) {
|
if (should_run_test || dry_run)
|
||||||
if (!test_runner.validate()) {
|
{
|
||||||
|
if (!test_runner.validate())
|
||||||
|
{
|
||||||
std::clog << "test did not validate: " << name << "\n";
|
std::clog << "test did not validate: " << name << "\n";
|
||||||
//throw std::runtime_error(std::string("test did not validate: ") + name);
|
//throw std::runtime_error(std::string("test did not validate: ") + name);
|
||||||
}
|
}
|
||||||
if (dry_run) {
|
if (dry_run)
|
||||||
|
{
|
||||||
std::clog << test_num << ") " << (test_runner.threads_ ? "threaded -> ": "")
|
std::clog << test_num << ") " << (test_runner.threads_ ? "threaded -> ": "")
|
||||||
<< name << "\n";
|
<< name << "\n";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
process_cpu_clock::time_point start;
|
process_cpu_clock::time_point start;
|
||||||
dur elapsed;
|
dur elapsed;
|
||||||
if (test_runner.threads_ > 0) {
|
if (test_runner.threads_ > 0)
|
||||||
|
{
|
||||||
boost::thread_group tg;
|
boost::thread_group tg;
|
||||||
for (unsigned i=0;i<test_runner.threads_;++i)
|
for (unsigned i=0;i<test_runner.threads_;++i)
|
||||||
{
|
{
|
||||||
boost::function<void()> _p;
|
tg.create_thread(test_runner);
|
||||||
_p = boost::bind(&T::operator(),&test_runner);
|
//tg.create_thread(boost::bind(&T::operator(),&test_runner));
|
||||||
tg.create_thread(_p);
|
|
||||||
}
|
}
|
||||||
start = process_cpu_clock::now();
|
start = process_cpu_clock::now();
|
||||||
tg.join_all();
|
tg.join_all();
|
||||||
elapsed = process_cpu_clock::now() - start;
|
elapsed = process_cpu_clock::now() - start;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
start = process_cpu_clock::now();
|
start = process_cpu_clock::now();
|
||||||
test_runner();
|
test_runner();
|
||||||
elapsed = process_cpu_clock::now() - start;
|
elapsed = process_cpu_clock::now() - start;
|
||||||
|
@ -75,7 +82,9 @@ void benchmark(T & test_runner, std::string const& name)
|
||||||
<< boost::chrono::duration_cast<milliseconds>(elapsed) << "\n";
|
<< boost::chrono::duration_cast<milliseconds>(elapsed) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (std::exception const& ex) {
|
}
|
||||||
|
catch (std::exception const& ex)
|
||||||
|
{
|
||||||
std::clog << "test runner did not complete: " << ex.what() << "\n";
|
std::clog << "test runner did not complete: " << ex.what() << "\n";
|
||||||
}
|
}
|
||||||
test_num++;
|
test_num++;
|
||||||
|
@ -594,6 +603,7 @@ struct test10
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#include <mapnik/wkt/wkt_factory.hpp>
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
#include "agg_conv_clipper.h"
|
#include "agg_conv_clipper.h"
|
||||||
#include "agg_path_storage.h"
|
#include "agg_path_storage.h"
|
||||||
|
@ -603,21 +613,19 @@ struct test11
|
||||||
{
|
{
|
||||||
unsigned iter_;
|
unsigned iter_;
|
||||||
unsigned threads_;
|
unsigned threads_;
|
||||||
boost::ptr_vector<geometry_type> paths_;
|
std::string wkt_in_;
|
||||||
mapnik::box2d<double> extent_;
|
mapnik::box2d<double> extent_;
|
||||||
typedef agg::conv_clipper<mapnik::geometry_type, agg::path_storage> poly_clipper;
|
typedef agg::conv_clipper<mapnik::geometry_type, agg::path_storage> poly_clipper;
|
||||||
explicit test11(unsigned iterations,
|
test11(unsigned iterations,
|
||||||
unsigned threads,
|
unsigned threads,
|
||||||
std::string wkt_in,
|
std::string wkt_in,
|
||||||
mapnik::box2d<double> const& extent)
|
mapnik::box2d<double> const& extent)
|
||||||
: iter_(iterations),
|
: iter_(iterations),
|
||||||
threads_(threads),
|
threads_(threads),
|
||||||
extent_(extent) {
|
wkt_in_(wkt_in),
|
||||||
if (!mapnik::from_wkt(wkt_in, paths_))
|
extent_(extent) {
|
||||||
{
|
|
||||||
throw std::runtime_error("Failed to parse WKT");
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validate()
|
bool validate()
|
||||||
{
|
{
|
||||||
|
@ -625,6 +633,11 @@ struct test11
|
||||||
}
|
}
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
|
boost::ptr_vector<geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
agg::path_storage ps;
|
agg::path_storage ps;
|
||||||
ps.move_to(extent_.minx(), extent_.miny());
|
ps.move_to(extent_.minx(), extent_.miny());
|
||||||
ps.line_to(extent_.minx(), extent_.maxy());
|
ps.line_to(extent_.minx(), extent_.maxy());
|
||||||
|
@ -632,7 +645,7 @@ struct test11
|
||||||
ps.line_to(extent_.maxx(), extent_.miny());
|
ps.line_to(extent_.maxx(), extent_.miny());
|
||||||
ps.close_polygon();
|
ps.close_polygon();
|
||||||
for (unsigned i=0;i<iter_;++i) {
|
for (unsigned i=0;i<iter_;++i) {
|
||||||
BOOST_FOREACH( geometry_type & geom, paths_)
|
BOOST_FOREACH( geometry_type & geom, paths)
|
||||||
{
|
{
|
||||||
poly_clipper clipped(geom,ps,
|
poly_clipper clipped(geom,ps,
|
||||||
agg::clipper_and,
|
agg::clipper_and,
|
||||||
|
@ -648,6 +661,51 @@ struct test11
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <mapnik/polygon_clipper.hpp>
|
||||||
|
|
||||||
|
struct test12
|
||||||
|
{
|
||||||
|
unsigned iter_;
|
||||||
|
unsigned threads_;
|
||||||
|
std::string wkt_in_;
|
||||||
|
|
||||||
|
mapnik::box2d<double> extent_;
|
||||||
|
typedef mapnik::polygon_clipper<mapnik::geometry_type> poly_clipper;
|
||||||
|
test12(unsigned iterations,
|
||||||
|
unsigned threads,
|
||||||
|
std::string wkt_in,
|
||||||
|
mapnik::box2d<double> const& extent)
|
||||||
|
: iter_(iterations),
|
||||||
|
threads_(threads),
|
||||||
|
wkt_in_(wkt_in),
|
||||||
|
extent_(extent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
boost::ptr_vector<geometry_type> paths;
|
||||||
|
if (!mapnik::from_wkt(wkt_in_, paths))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse WKT");
|
||||||
|
}
|
||||||
|
for (unsigned i=0;i<iter_;++i)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( geometry_type & geom, paths)
|
||||||
|
{
|
||||||
|
poly_clipper clipped(extent_, geom);
|
||||||
|
unsigned cmd;
|
||||||
|
double x,y;
|
||||||
|
while ((cmd = geom.vertex(&x, &y)) != SEG_END) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main( int argc, char** argv)
|
int main( int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
|
@ -785,10 +843,25 @@ int main( int argc, char** argv)
|
||||||
std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
|
std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
|
||||||
(std::istreambuf_iterator<char>()) );
|
(std::istreambuf_iterator<char>()) );
|
||||||
mapnik::box2d<double> clipping_box(0,0,40,40);
|
mapnik::box2d<double> clipping_box(0,0,40,40);
|
||||||
|
|
||||||
test11 runner(100000,10,wkt_in,clipping_box);
|
test11 runner(100000,10,wkt_in,clipping_box);
|
||||||
benchmark(runner,"clipping polygon with agg_conv_clipper");
|
benchmark(runner,"clipping polygon with agg_conv_clipper");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string filename_("benchmark/data/polygon.wkt");
|
||||||
|
std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
|
||||||
|
if (!in.is_open())
|
||||||
|
throw std::runtime_error("could not open: '" + filename_ + "'");
|
||||||
|
std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
|
||||||
|
(std::istreambuf_iterator<char>()) );
|
||||||
|
mapnik::box2d<double> clipping_box(0,0,40,40);
|
||||||
|
|
||||||
|
test12 runner(100000,10,wkt_in,clipping_box);
|
||||||
|
benchmark(runner,"clipping polygon with mapnik::polygon_clipper");
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "...benchmark done\n";
|
std::cout << "...benchmark done\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue