From 018a91030614c20aec00f580fb65b02985bec366 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 19 Nov 2019 13:38:38 -0800 Subject: [PATCH] Benchmark tweaks --- benchmark/deep_stack_leaf.cpp | 102 +++++++++++++++++++++---------- benchmark/deep_stack_outcome.cpp | 96 ++++++++++++++++++----------- meson.build | 8 ++- 3 files changed, 137 insertions(+), 69 deletions(-) diff --git a/benchmark/deep_stack_leaf.cpp b/benchmark/deep_stack_leaf.cpp index c44c136..74a4194 100644 --- a/benchmark/deep_stack_leaf.cpp +++ b/benchmark/deep_stack_leaf.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #ifndef LEAF_NO_EXCEPTIONS @@ -240,51 +241,90 @@ int runner( int failure_rate ) noexcept ////////////////////////////////////// -template -int print_elapsed_time( F && f ) +char const * csv_name = 0; + +std::fstream append_csv() +{ + if( !csv_name ) + { + assert(*csv_name); + return { }; + } + else if( FILE * f = fopen("benchmark.csv","rb") ) + { + fclose(f); + return std::fstream("benchmark.csv", std::fstream::out | std::fstream::app); + } + else + { + std::fstream fs("benchmark.csv", std::fstream::out | std::fstream::app); + fs << ",\"Check, noinline\",\"Check, inline\",\"Handle some, noinline\", \"Handle some, inline\",\"Error rate\"\n"; + return fs; + } +} + +template +int print_elapsed_time( int iteration_count, F && f ) { auto start = std::chrono::system_clock::now(); int val = 0; - for( int i = 0; i!=Iterations; ++i ) + for( int i = 0; i!=iteration_count; ++i ) val += std::forward(f)(); auto stop = std::chrono::system_clock::now(); - std::cout << std::setw(10) << std::chrono::duration_cast(stop-start).count(); + int elapsed = std::chrono::duration_cast(stop-start).count(); + std::cout << std::right << std::setw(8) << elapsed; + append_csv() << ',' << elapsed; return val; } ////////////////////////////////////// -int main() +template +int benchmark_type( char const * type_name, int iteration_count ) { - int const depth = 200; - int const iteration_count = 5000; - int const test_rates[ ] = { 5, 50, 95 }; + int const test_rates[ ] = { 10, 50, 90 }; int x=0; - - std::cout << iteration_count << " iterations, call depth " << depth << ", sizeof(e_heavy_payload) = " << sizeof(e_heavy_payload); + std::cout << "----------------|--------------------|----------|-------|--------"; for( auto fr : test_rates ) { - std::cout << "\n" - "\nError type | At each level | Inlining | Elapsed μs" - "\n----------------|--------------------|----------|----------- failure rate = " << fr << '%'; - std::cout << "\ne_error_code | LEAF_AUTO | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_error_code | LEAF_AUTO | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_error_code | try_handle_some | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_error_code | try_handle_some | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | LEAF_AUTO | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | LEAF_AUTO | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | try_handle_some | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | try_handle_some | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); + append_csv() << "LEAF"; + std::cout << '\n' << std::left << std::setw(16) << type_name << "| LEAF_AUTO | Disabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + std::cout << '\n' << std::left << std::setw(16) << type_name << "| LEAF_AUTO | Enabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + std::cout << '\n' << std::left << std::setw(16) << type_name << "| try_handle_some | Disabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + std::cout << '\n' << std::left << std::setw(16) << type_name << "| try_handle_some | Enabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + append_csv() << ',' << fr << '\n'; }; - - std::cout << std::endl; + std::cout << '\n'; return x; } + +////////////////////////////////////// + +int main( int argc, char const * argv[] ) +{ + int const depth = 100; + int const iteration_count = 1000; + if( argc==2 ) + csv_name = argv[1]; + else if( argc!=1 ) + { + std::cerr << "Bad command line\n"; + return 1; + } + std::cout << + iteration_count << " iterations, call depth " << depth << ", sizeof(e_heavy_payload) = " << sizeof(e_heavy_payload) << "\n" + "LEAF\n" + " | | Function | Error | Elapsed\n" + "Error type | At each level | inlining | rate | (μs)\n"; + return + benchmark_type("e_error_code", iteration_count) + + benchmark_type("e_heavy_payload", iteration_count); +} diff --git a/benchmark/deep_stack_outcome.cpp b/benchmark/deep_stack_outcome.cpp index 06ae113..a78213d 100644 --- a/benchmark/deep_stack_outcome.cpp +++ b/benchmark/deep_stack_outcome.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #ifndef BOOST_NO_EXCEPTIONS @@ -218,51 +219,76 @@ int runner( int failure_rate ) noexcept ////////////////////////////////////// -template -int print_elapsed_time( F && f ) +std::fstream append_csv() +{ + if( FILE * f = fopen("benchmark.csv","rb") ) + { + fclose(f); + return std::fstream("benchmark.csv", std::fstream::out | std::fstream::app); + } + else + { + std::fstream fs("benchmark.csv", std::fstream::out | std::fstream::app); + fs << ",\"Check, noinline\",\"Check, inline\",\"Handle some, noinline\", \"Handle some, inline\",\"Error rate\"\n"; + return fs; + } +} + +template +int print_elapsed_time( int iteration_count, F && f ) { auto start = std::chrono::system_clock::now(); int val = 0; - for( int i = 0; i!=Iterations; ++i ) + for( int i = 0; i!=iteration_count; ++i ) val += std::forward(f)(); auto stop = std::chrono::system_clock::now(); - std::cout << std::setw(10) << std::chrono::duration_cast(stop-start).count(); + int elapsed = std::chrono::duration_cast(stop-start).count(); + std::cout << std::right << std::setw(8) << elapsed; + append_csv() << ',' << elapsed; return val; } ////////////////////////////////////// +template +int benchmark_type( char const * type_name, int iteration_count ) +{ + int const test_rates[ ] = { 10, 50, 90 }; + int x=0; + std::cout << "----------------|--------------------|----------|-------|--------"; + for( auto fr : test_rates ) + { + append_csv() << "Outcome"; + std::cout << '\n' << std::left << std::setw(16) << type_name << "| OUTCOME_TRY | Disabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + std::cout << '\n' << std::left << std::setw(16) << type_name << "| OUTCOME_TRY | Enabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + std::cout << '\n' << std::left << std::setw(16) << type_name << "| Handle some errors | Disabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + std::cout << '\n' << std::left << std::setw(16) << type_name << "| Handle some errors | Enabled | " << std::right << std::setw(4) << fr << "% |"; + std::srand(0); + x += print_elapsed_time( iteration_count, [=] { return runner>(fr); } ); + append_csv() << ',' << fr << '\n'; + }; + std::cout << '\n'; + return x; +} + +////////////////////////////////////// + int main() { - int const depth = 200; - int const iteration_count = 5000; - int const test_rates[ ] = { 5, 50, 95 }; - int x=0; - - std::cout << iteration_count << " iterations, call depth " << depth << ", sizeof(e_heavy_payload) = " << sizeof(e_heavy_payload); - for( auto fr : test_rates ) - { - std::cout << "\n" - "\nError type | At each level | Inlining | Elapsed μs" - "\n----------------|--------------------|----------|----------- failure rate = " << fr << '%'; - std::cout << "\ne_error_code | OUTCOME_TRY | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_error_code | OUTCOME_TRY | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_error_code | Handle some errors | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_error_code | Handle some errors | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | OUTCOME_TRY | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | OUTCOME_TRY | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | Handle some errors | Disabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - std::cout << "\ne_heavy_payload | Handle some errors | Enabled | "; - x += print_elapsed_time( [=] { return runner>(fr); } ); - }; - - std::cout << std::endl; - return x; + int const depth = 100; + int const iteration_count = 1000; + std::cout << + iteration_count << " iterations, call depth " << depth << ", sizeof(e_heavy_payload) = " << sizeof(e_heavy_payload) << "\n" + "Outcome\n" + " | | Function | Error | Elapsed\n" + "Error type | At each level | inlining | rate | (μs)\n"; + return + benchmark_type("e_error_code", iteration_count) + + benchmark_type("e_heavy_payload", iteration_count); } diff --git a/meson.build b/meson.build index 0e40c59..3bc6360 100644 --- a/meson.build +++ b/meson.build @@ -173,7 +173,9 @@ if exceptions endif endif -executable('deep_stack_leaf', 'benchmark/deep_stack_leaf.cpp', dependencies: [leaf]) -if get_option('boost_examples') - executable('deep_stack_outcome', 'benchmark/deep_stack_outcome.cpp', dependencies: [leaf,boost_headers], override_options: ['cpp_std=c++17'] ) +if get_option('cpp_eh')=='none' + executable('deep_stack_leaf', 'benchmark/deep_stack_leaf.cpp', dependencies: [leaf]) + if get_option('boost_examples') + executable('deep_stack_outcome', 'benchmark/deep_stack_outcome.cpp', dependencies: [leaf,boost_headers], override_options: ['cpp_std=c++17'] ) + endif endif