voronoi_benchmark_points.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Boost.Polygon library voronoi_benchmark.cpp file
  2. // Copyright Andrii Sydorchuk 2010-2012.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org for updates, documentation, and revision history.
  7. #include <algorithm>
  8. #include <iomanip>
  9. #include <iostream>
  10. #include <fstream>
  11. #include <numeric>
  12. #include <vector>
  13. #include <utility>
  14. #include <boost/random/mersenne_twister.hpp>
  15. #include <boost/timer/timer.hpp>
  16. typedef boost::int32_t int32;
  17. using boost::timer::cpu_times;
  18. using boost::timer::nanosecond_type;
  19. // Include for the Boost.Polygon Voronoi library.
  20. #include <boost/polygon/voronoi.hpp>
  21. typedef boost::polygon::default_voronoi_builder VB_BOOST;
  22. typedef boost::polygon::voronoi_diagram<double> VD_BOOST;
  23. // Includes for the CGAL library.
  24. #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
  25. #include <CGAL/Delaunay_triangulation_2.h>
  26. typedef CGAL::Exact_predicates_inexact_constructions_kernel CGAL_KERNEL;
  27. typedef CGAL::Delaunay_triangulation_2<CGAL_KERNEL> DT_CGAL;
  28. typedef CGAL_KERNEL::Point_2 POINT_CGAL;
  29. // Includes for the S-Hull library.
  30. #include <s_hull.h>
  31. const int RANDOM_SEED = 27;
  32. const int NUM_TESTS = 6;
  33. const int NUM_POINTS[] = {10, 100, 1000, 10000, 100000, 1000000};
  34. const int NUM_RUNS[] = {100000, 10000, 1000, 100, 10, 1};
  35. std::ofstream bf("benchmark_points.txt",
  36. std::ios_base::out | std::ios_base::app);
  37. boost::timer::cpu_timer timer;
  38. void format_line(int num_points, int num_tests, double time_per_test) {
  39. bf << "| " << std::setw(16) << num_points << " ";
  40. bf << "| " << std::setw(15) << num_tests << " ";
  41. bf << "| " << std::setw(17) << time_per_test << " ";
  42. bf << "|" << std::endl;
  43. }
  44. double get_elapsed_secs() {
  45. cpu_times elapsed_times(timer.elapsed());
  46. return 1E-9 * static_cast<double>(
  47. elapsed_times.system + elapsed_times.user);
  48. }
  49. void run_boost_voronoi_test() {
  50. boost::mt19937 gen(RANDOM_SEED);
  51. bf << "Boost.Polygon Voronoi Diagram of Points:\n";
  52. for (int i = 0; i < NUM_TESTS; ++i) {
  53. timer.start();
  54. for (int j = 0; j < NUM_RUNS[i]; ++j) {
  55. VB_BOOST vb;
  56. VD_BOOST vd;
  57. for (int k = 0; k < NUM_POINTS[i]; ++k) {
  58. int32 x = static_cast<int32>(gen());
  59. int32 y = static_cast<int32>(gen());
  60. vb.insert_point(x, y);
  61. }
  62. vb.construct(&vd);
  63. }
  64. double time_per_test = get_elapsed_secs() / NUM_RUNS[i];
  65. format_line(NUM_POINTS[i], NUM_RUNS[i], time_per_test);
  66. }
  67. bf << "\n";
  68. }
  69. void run_cgal_delaunay_test() {
  70. boost::mt19937 gen(RANDOM_SEED);
  71. bf << "CGAL Delaunay Triangulation of Points:\n";
  72. for (int i = 0; i < NUM_TESTS; ++i) {
  73. timer.start();
  74. for (int j = 0; j < NUM_RUNS[i]; ++j) {
  75. DT_CGAL dt;
  76. std::vector<POINT_CGAL> points;
  77. for (int k = 0; k < NUM_POINTS[i]; ++k) {
  78. int32 x = static_cast<int32>(gen());
  79. int32 y = static_cast<int32>(gen());
  80. points.push_back(POINT_CGAL(x, y));
  81. }
  82. // CGAL's implementation sorts points along
  83. // the Hilbert curve implicitly to improve
  84. // spatial ordering of the input geometries.
  85. dt.insert(points.begin(), points.end());
  86. }
  87. double time_per_test = get_elapsed_secs() / NUM_RUNS[i];
  88. format_line(NUM_POINTS[i], NUM_RUNS[i], time_per_test);
  89. }
  90. bf << "\n";
  91. }
  92. void run_shull_delaunay_test() {
  93. boost::mt19937 gen(RANDOM_SEED);
  94. bf << "S-Hull Delaunay Triangulation of Points:\n";
  95. // This value is required by S-Hull as it doesn't seem to support properly
  96. // coordinates with the absolute value higher than 100.
  97. float koef = 100.0 / (1 << 16) / (1 << 15);
  98. for (int i = 0; i < NUM_TESTS; ++i) {
  99. timer.start();
  100. for (int j = 0; j < NUM_RUNS[i]; ++j) {
  101. // S-Hull doesn't deal properly with duplicates so we need
  102. // to eliminate them before running the algorithm.
  103. std::vector< pair<int32, int32> > upts;
  104. std::vector<Shx> pts;
  105. std::vector<Triad> triads;
  106. Shx pt;
  107. for (int k = 0; k < NUM_POINTS[i]; ++k) {
  108. int32 x = static_cast<int32>(gen());
  109. int32 y = static_cast<int32>(gen());
  110. upts.push_back(std::make_pair(x, y));
  111. }
  112. // Absolutely the same code is used by the Boost.Polygon Voronoi library.
  113. std::sort(upts.begin(), upts.end());
  114. upts.erase(std::unique(upts.begin(), upts.end()), upts.end());
  115. for (int k = 0; k < upts.size(); ++k) {
  116. pt.r = koef * upts[k].first;
  117. pt.c = koef * upts[k].second;
  118. pt.id = k;
  119. pts.push_back(pt);
  120. }
  121. s_hull_del_ray2(pts, triads);
  122. }
  123. double time_per_test = get_elapsed_secs() / NUM_RUNS[i];
  124. format_line(NUM_POINTS[i], NUM_RUNS[i], time_per_test);
  125. }
  126. bf << "\n";
  127. }
  128. int main() {
  129. bf << std::setiosflags(std::ios::right | std::ios::fixed)
  130. << std::setprecision(6);
  131. run_boost_voronoi_test();
  132. run_cgal_delaunay_test();
  133. run_shull_delaunay_test();
  134. bf.close();
  135. return 0;
  136. }