Merge pull request #3337 from lightmare/normalize-angle
speed up util::normalize_angle for large values
This commit is contained in:
commit
187c1df332
30 changed files with 111 additions and 42 deletions
|
@ -18,40 +18,19 @@ test_env.Append(CPPDEFINES = env['LIBMAPNIK_DEFINES'])
|
||||||
if test_env['HAS_CAIRO']:
|
if test_env['HAS_CAIRO']:
|
||||||
test_env.PrependUnique(CPPPATH=test_env['CAIRO_CPPPATHS'])
|
test_env.PrependUnique(CPPPATH=test_env['CAIRO_CPPPATHS'])
|
||||||
test_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
test_env.Append(CPPDEFINES = '-DHAVE_CAIRO')
|
||||||
|
test_env.PrependUnique(CPPPATH='include', delete_existing=True)
|
||||||
test_env['LINKFLAGS'] = copy(test_env['LIBMAPNIK_LINKFLAGS'])
|
test_env['LINKFLAGS'] = copy(test_env['LIBMAPNIK_LINKFLAGS'])
|
||||||
if env['PLATFORM'] == 'Darwin':
|
if env['PLATFORM'] == 'Darwin':
|
||||||
test_env.Append(LINKFLAGS='-F/ -framework CoreFoundation')
|
test_env.Append(LINKFLAGS='-F/ -framework CoreFoundation')
|
||||||
|
|
||||||
test_env_local = test_env.Clone()
|
test_env_local = test_env.Clone()
|
||||||
|
|
||||||
#benchmarks = glob.glob('test*cpp')
|
benchmarks = glob.glob("src/*.cpp")
|
||||||
benchmarks = [
|
|
||||||
#"test_array_allocation.cpp",
|
for src in benchmarks:
|
||||||
#"test_png_encoding1.cpp",
|
name, ext = os.path.splitext(os.path.basename(src))
|
||||||
#"test_png_encoding2.cpp",
|
out = os.path.join("out", name)
|
||||||
#"test_to_string1.cpp",
|
test_program = test_env_local.Program(out, source=[src])
|
||||||
#"test_to_string2.cpp",
|
|
||||||
#"test_to_bool.cpp",
|
|
||||||
#"test_to_double.cpp",
|
|
||||||
#"test_to_int.cpp",
|
|
||||||
#"test_utf_encoding.cpp"
|
|
||||||
"test_polygon_clipping.cpp",
|
|
||||||
#"test_polygon_clipping_rendering.cpp",
|
|
||||||
"test_proj_transform1.cpp",
|
|
||||||
"test_expression_parse.cpp",
|
|
||||||
"test_face_ptr_creation.cpp",
|
|
||||||
"test_font_registration.cpp",
|
|
||||||
"test_rendering.cpp",
|
|
||||||
"test_rendering_shared_map.cpp",
|
|
||||||
"test_offset_converter.cpp",
|
|
||||||
"test_marker_cache.cpp",
|
|
||||||
"test_quad_tree.cpp",
|
|
||||||
"test_noop_rendering.cpp",
|
|
||||||
"test_getline.cpp",
|
|
||||||
# "test_numeric_cast_vs_static_cast.cpp",
|
|
||||||
]
|
|
||||||
for cpp_test in benchmarks:
|
|
||||||
test_program = test_env_local.Program('out/'+cpp_test.replace('.cpp',''), source=[cpp_test])
|
|
||||||
if 'install' in COMMAND_LINE_TARGETS:
|
if 'install' in COMMAND_LINE_TARGETS:
|
||||||
env.Alias('install',test_program)
|
env.Alias('install',test_program)
|
||||||
#Depends(test_program, env.subst('../src/%s' % env['MAPNIK_LIB_NAME']))
|
#Depends(test_program, env.subst('../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath> // log10, round
|
#include <cmath> // log10, round
|
||||||
#include <cstdio> // snprintf
|
#include <cstdio> // snprintf
|
||||||
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -239,14 +240,19 @@ int run(T const& test_runner, std::string const& name)
|
||||||
big_number_fmt itersf(4, total_iters);
|
big_number_fmt itersf(4, total_iters);
|
||||||
big_number_fmt ips(5, total_iters / seconds<double>(elapsed_nonzero).count());
|
big_number_fmt ips(5, total_iters / seconds<double>(elapsed_nonzero).count());
|
||||||
|
|
||||||
|
std::clog << std::left << std::setw(43) << name;
|
||||||
|
std::clog << std::resetiosflags(std::ios::adjustfield);
|
||||||
|
if (num_threads > 0) {
|
||||||
|
std::clog << ' ' << std::setw(3) << num_threads
|
||||||
|
<< " worker" << (num_threads > 1 ? "s" : " ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::clog << " main thread";
|
||||||
|
}
|
||||||
std::snprintf(msg, sizeof(msg),
|
std::snprintf(msg, sizeof(msg),
|
||||||
"%-43s %3zu thread(s) %*.0f%s iters %6.0f milliseconds %*.0f%s i/s\n",
|
" %*.0f%s iters %6.0f milliseconds %*.0f%s i/t/s\n",
|
||||||
name.c_str(),
|
itersf.w, itersf.v, itersf.u, dur_total,
|
||||||
num_threads,
|
ips.w, ips.v, ips.u);
|
||||||
itersf.w, itersf.v, itersf.u,
|
|
||||||
dur_total,
|
|
||||||
ips.w, ips.v, ips.u
|
|
||||||
);
|
|
||||||
std::clog << msg;
|
std::clog << msg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ function run {
|
||||||
local threads="$2"
|
local threads="$2"
|
||||||
local iters="$3"
|
local iters="$3"
|
||||||
shift 3
|
shift 3
|
||||||
$runner --threads 1 --iterations $iters "$@"
|
$runner --threads 0 --iterations $iters "$@"
|
||||||
if test $threads -gt 0; then
|
if test $threads -gt 0; then
|
||||||
$runner --threads $threads --iterations $((iters/threads)) "$@"
|
$runner --threads $threads --iterations $((iters/threads)) "$@"
|
||||||
fi
|
fi
|
||||||
|
@ -28,6 +28,7 @@ run test_expression_parse 10 10000
|
||||||
run test_face_ptr_creation 10 1000
|
run test_face_ptr_creation 10 1000
|
||||||
run test_font_registration 10 100
|
run test_font_registration 10 100
|
||||||
run test_offset_converter 10 1000
|
run test_offset_converter 10 1000
|
||||||
|
#run normalize_angle 0 1000000 --min-duration=0.2
|
||||||
|
|
||||||
# commented since this is really slow on travis
|
# commented since this is really slow on travis
|
||||||
: '
|
: '
|
||||||
|
|
69
benchmark/src/normalize_angle.cpp
Normal file
69
benchmark/src/normalize_angle.cpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include "bench_framework.hpp"
|
||||||
|
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct bench_func : benchmark::test_case
|
||||||
|
{
|
||||||
|
T (* const func_)(T);
|
||||||
|
T const value_;
|
||||||
|
|
||||||
|
bench_func(mapnik::parameters const& params, T (*func)(T), T value)
|
||||||
|
: test_case(params), func_(func), value_(value) {}
|
||||||
|
|
||||||
|
bool validate() const { return true; }
|
||||||
|
|
||||||
|
bool operator() () const
|
||||||
|
{
|
||||||
|
for (auto i = this->iterations_; i-- > 0; )
|
||||||
|
{
|
||||||
|
func_(value_);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BENCH_FUNC1(func, value) \
|
||||||
|
run<bench_func<double>>(#func "(" #value ")", func, value)
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return benchmark::sequencer(argc, argv)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +3)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +6)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +9)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +12)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +15)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +20)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +30)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +40)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +50)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +70)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +90)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +110)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +130)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +157)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +209)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +314)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +628)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, +942)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -3)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -6)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -9)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -12)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -15)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -20)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -30)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -40)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -50)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -70)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -90)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -110)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -130)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -157)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -209)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -314)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -628)
|
||||||
|
.BENCH_FUNC1(mapnik::util::normalize_angle, -942)
|
||||||
|
.done();
|
||||||
|
}
|
|
@ -27,9 +27,11 @@
|
||||||
|
|
||||||
namespace mapnik { namespace util {
|
namespace mapnik { namespace util {
|
||||||
|
|
||||||
|
constexpr double pi = 3.1415926535897932384626433832795;
|
||||||
|
constexpr double tau = 6.283185307179586476925286766559;
|
||||||
|
|
||||||
MAPNIK_DECL double normalize_angle(double angle);
|
MAPNIK_DECL double normalize_angle(double angle);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
22
src/math.cpp
22
src/math.cpp
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/util/math.hpp>
|
#include <mapnik/util/math.hpp>
|
||||||
#include <mapnik/global.hpp>
|
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -33,13 +32,26 @@ namespace util {
|
||||||
|
|
||||||
double normalize_angle(double angle)
|
double normalize_angle(double angle)
|
||||||
{
|
{
|
||||||
while (angle >= M_PI)
|
if (angle > pi)
|
||||||
{
|
{
|
||||||
angle -= 2.0 * M_PI;
|
if (angle > 16 * tau)
|
||||||
|
{
|
||||||
|
// the angle is too large; better compute the remainder
|
||||||
|
// directly to avoid subtracting circles ad infinitum
|
||||||
|
return std::remainder(angle, tau);
|
||||||
}
|
}
|
||||||
while (angle < -M_PI)
|
// std::remainder would take longer than a few subtractions
|
||||||
|
while ((angle -= tau) > pi)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if (angle < -pi)
|
||||||
{
|
{
|
||||||
angle += 2.0 * M_PI;
|
if (angle < -16 * tau)
|
||||||
|
{
|
||||||
|
return std::remainder(angle, tau);
|
||||||
|
}
|
||||||
|
while ((angle += tau) < -pi)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue