Skip to content
Browse files

support for Android NDK

  • Loading branch information...
1 parent 5560b43 commit edd6c2214a83669b14e8be7e6e17f09a8107a0fc @vstadnik committed Mar 21, 2013
Showing with 740 additions and 361 deletions.
  1. +1 −1 README
  2. +28 −294 test/boost_performance.cpp
  3. +709 −55 test/perform_tests.hpp
  4. +2 −11 test/timer_chrono.hpp
View
2 README
@@ -66,6 +66,6 @@ COMPILERS
- MSVC++ 9/10 (Visual Studio 2008/2010, including Express editions) ;
- GCC 4.5.2 (tested using MinGW) ;
-
+- GCC 4.6, GCC 4.7 using Android NDK and ADT Eclipse ;
View
322 test/boost_performance.cpp
@@ -12,313 +12,47 @@
/////////////////////////////////////////////////////////////////
-// standard containers
-#include <vector>
-#include <deque>
-#include <list>
-#include <set>
+#include "perform_tests.hpp"
-// boost containers
-#include <boost/container/vector.hpp>
-#include <boost/container/deque.hpp>
-#include <boost/container/list.hpp>
-#include <boost/container/set.hpp>
-#include <boost/container/flat_set.hpp>
-#include <boost/container/stable_vector.hpp>
-
-// do not link serialization library
-#define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
-//
-// "node compression" improves locality of reference and hence performance
-//#define BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES
-//
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/random_access_index.hpp>
-
-
-
-// std_ext_adv containers
-#include "bpt_sequence.hpp"
-#include "bpt_set.hpp"
-//
-// dynamically allocated augmented B+ tree from project:
-// https://github.com/vstadnik/stl_ext_adv
-//
-// can be used to compare performance and effect of
-// locality of reference with array based B+ trees ;
-//
-//#include "bp_tree_idx.hpp"
-
-#include "test_helpers.hpp"
-#include "timer_chrono.hpp"
-
-
-// methods for measurements of performance of containers
-// that support interfaces of C++ STL containers
-namespace test_performance
-{
-
- std::vector<size_t> vec_value ;
- std::vector<size_t> vec_dist ;
-
-
- void initialize_test_data ( const size_t sz_test )
- {
- vec_value . clear ( ) ;
- vec_dist . clear ( ) ;
- test_std_ext_adv::fill_rand ( vec_value , sz_test , 1 , 1 ) ;
- test_std_ext_adv::fill_rand ( vec_dist , sz_test , 1 , 1 ) ;
- }
-
-
- template < class _Ty_Contr >
- void advance_insert
- (
- const size_t sz_test ,
- std::string const & comment ,
- _Ty_Contr & contr_test
- )
- {
- typedef typename _Ty_Contr::iterator _Iter ;
- typedef typename _Iter::difference_type _DistType ;
-
- // insert sz_test/4 elements
- {
- std::vector<size_t>::iterator
- iter_4 = vec_value.begin() + static_cast<_DistType>(sz_test/4) ;
- _Ty_Contr contr_temp ( vec_value.begin() , iter_4 ) ;
- contr_test = contr_temp ;
- }
-
- size_t value = 0 ;
- _DistType dist = 0 ;
- _Iter iter ;
-
- TimerChrono timer ;
- timer . Start ( ) ;
-
- for ( size_t i = sz_test/4 ; i < sz_test ; ++i )
- {
- // in this test ( i == contr_test.size() ) ;
- dist = static_cast<_DistType>( vec_dist[i] % i ) ;
- value = vec_value [ i ] ;
- iter = contr_test . begin ( ) ;
- std::advance ( iter , dist ) ;
- contr_test . insert ( iter , value ) ;
- }
-
- timer . Stop ( ) ;
- timer . PrintTime ( comment ) ;
- }
-
-
- // the test of sequential processing,
- // its running time depends on locality
- // of reference of input container
- template < class _Ty_Contr >
- size_t std_accumulate ( _Ty_Contr const & contr_test )
- {
- typename
- _Ty_Contr::const_iterator
- it_cur = contr_test . begin ( ) ,
- it_end = contr_test . end ( ) ;
- size_t res = 0 ;
- size_t n_runs = 10 ;
- std::string comment ( "accumulate" ) ;
-
- TimerChrono timer ;
- timer . Start ( ) ;
-
- for ( size_t i = 0 ; i < n_runs ; ++i )
- {
- res += std::accumulate ( it_cur , it_end , 0 ) ;
- }
-
- timer . Stop ( ) ;
- timer . PrintTime ( comment ) ;
-
- // to compare results for different containers and
- // to avoid compiler optimization effect
- std::cout << res << std::endl << std::endl ;
- return res ;
- }
-
-
- void bpt_sequence_array ( const size_t sz_test )
- {
- std_ext_adv::sequence<size_t> bpt_seqce_array ;
- advance_insert ( sz_test , "std_ext_adv::sequence_array" , bpt_seqce_array ) ;
- std_accumulate ( bpt_seqce_array ) ;
- }
-
- void bpt_multiset_array ( const size_t sz_test )
- {
- std_ext_adv::multiset<size_t> bpt_m_set_array ;
- advance_insert ( sz_test , "std_ext_adv::multiset_array" , bpt_m_set_array ) ;
- std_accumulate ( bpt_m_set_array ) ;
- }
-
- // test of dynamically allocated B+ tree "bp_tree_idx.hpp"
-// void bpt_sequence_list ( const size_t sz_test )
-// {
-// std_ext_adv::sequence<size_t, std::allocator<size_t>,
-// std_ext_adv::bp_tree_idx>
-// bpt_seqce_list ;
-// advance_insert ( sz_test , "std_ext_adv::sequence_list" , bpt_seqce_list ) ;
-// std_accumulate ( bpt_seqce_list ) ;
-// }
-
- void std_vector ( const size_t sz_test )
- {
- std::vector<size_t> std_vector ;
- advance_insert ( sz_test , "std::vector" , std_vector ) ;
- std_accumulate ( std_vector ) ;
- }
-
- void std_deque ( const size_t sz_test )
- {
- std::deque<size_t> std_deque ;
- advance_insert ( sz_test , "std::deque" , std_deque ) ;
- std_accumulate ( std_deque ) ;
- }
-
- void std_list ( const size_t sz_test )
- {
- std::list<size_t> std_list ;
- advance_insert ( sz_test , "std::list" , std_list ) ;
- std_accumulate ( std_list ) ;
- }
-
- void std_multiset ( const size_t sz_test )
- {
- std::multiset<size_t> std_m_set ;
- advance_insert ( sz_test , "std::multiset" , std_m_set ) ;
- std_accumulate ( std_m_set ) ;
- }
-
- void boost_vector ( const size_t sz_test )
- {
- boost::container::vector<size_t> b_vector ;
- advance_insert ( sz_test , "boost::vector" , b_vector ) ;
- std_accumulate ( b_vector ) ;
- }
-
- void boost_deque ( const size_t sz_test )
- {
- boost::container::deque<size_t> b_deque ;
- advance_insert ( sz_test , "boost::deque" , b_deque ) ;
- std_accumulate ( b_deque ) ;
- }
-
- void boost_list ( const size_t sz_test )
- {
- boost::container::list<size_t> b_list ;
- advance_insert ( sz_test , "boost::list" , b_list ) ;
- std_accumulate ( b_list ) ;
- }
-
- void boost_multiset ( const size_t sz_test )
- {
- boost::container::multiset<size_t> b_m_set ;
- advance_insert ( sz_test , "boost::multiset" , b_m_set ) ;
- std_accumulate ( b_m_set ) ;
- }
-
- void boost_flat_multiset ( const size_t sz_test )
- {
- boost::container::flat_multiset<size_t> b_fm_set ;
- advance_insert ( sz_test , "boost::flat_multiset" , b_fm_set ) ;
- std_accumulate ( b_fm_set ) ;
- }
-
- void boost_stable_vector ( const size_t sz_test )
- {
- boost::container::stable_vector<size_t> b_stable_vector ;
- advance_insert ( sz_test , "boost::stable_vector" , b_stable_vector ) ;
- std_accumulate ( b_stable_vector ) ;
- }
-
-
- using namespace boost ;
- using namespace boost::multi_index;
-
- void boost_m_idx_multiset ( const size_t sz_test )
- {
- multi_index_container<size_t, indexed_by<ordered_non_unique<identity<size_t> > > >
- mi_m_set ;
- advance_insert ( sz_test , "boost::m_idx::multiset" , mi_m_set ) ;
- std_accumulate ( mi_m_set ) ;
- }
-
-
- // class adaptor to emulate std::list,
- // for more details see Boost.MultiIndex documentation
- template < typename T >
- struct mutable_value
- {
- mutable_value ( const T & _t ) : t(_t) { }
- operator T&() const { return t; }
- private:
- mutable T t ;
- } ;
-
- void boost_m_idx_list ( const size_t sz_test )
- {
- multi_index_container<mutable_value<size_t>, indexed_by<sequenced< > > >
- mi_list ;
- advance_insert ( sz_test , "boost::m_idx::list" , mi_list ) ;
- std_accumulate ( mi_list ) ;
- }
-
- void boost_m_idx_random_access ( const size_t sz_test )
- {
- // this container can be tested too
- // multi_index_container<size_t, indexed_by<random_access< > > >
- multi_index_container<mutable_value<size_t>, indexed_by<random_access< > > >
- mi_random_access ;
- advance_insert ( sz_test , "boost::m_idx::random_access" , mi_random_access ) ;
- std_accumulate ( mi_random_access ) ;
- }
-
-
-} // namespace test_performance ;
-
-
-int main ( int argc , char* argv[] )
+int main ( )
{
const size_t n_test = 1000 ;
+ std::string str_test ;
std::cout << "performance test for N=" << n_test
<< " elements;" << std::endl << std::endl ;
- // use the same set of test data for every container
- test_performance::initialize_test_data ( n_test ) ;
+ test_performance::TestContainers<size_t> test ( "<size_t>" ) ;
+
+ // the same set of data is used to test every container
+ test . InitializeData ( n_test ) ;
- test_performance::bpt_sequence_array ( n_test ) ;
- test_performance::bpt_multiset_array ( n_test ) ;
-// test_performance::bpt_sequence_list ( n_test ) ;
+ // standard containers
+ test . std_vector ( str_test ) ;
+ test . std_list ( str_test ) ;
+ test . std_deque ( str_test ) ;
+ test . std_multiset ( str_test ) ;
- test_performance::std_vector ( n_test ) ;
- test_performance::std_deque ( n_test ) ;
- test_performance::std_list ( n_test ) ;
- test_performance::std_multiset ( n_test ) ;
+ // containers using augmented B+ trees
+ test . bpt_sequence_array ( str_test ) ;
+ test . bpt_multiset_array ( str_test ) ;
+// test . bpt_sequence_list ( str_test ) ;
- test_performance::boost_vector ( n_test ) ;
- test_performance::boost_deque ( n_test ) ;
- test_performance::boost_list ( n_test ) ;
- test_performance::boost_multiset ( n_test ) ;
- test_performance::boost_stable_vector ( n_test ) ;
- test_performance::boost_flat_multiset ( n_test ) ;
+ // Boost containers
+ test . boost_vector ( str_test ) ;
+ test . boost_list ( str_test ) ;
+ test . boost_deque ( str_test ) ;
+ test . boost_multiset ( str_test ) ;
+ test . boost_stable_vector ( str_test ) ;
+ test . boost_flat_multiset ( str_test ) ;
- test_performance::boost_m_idx_multiset( n_test ) ;
- test_performance::boost_m_idx_list ( n_test ) ;
- test_performance::boost_m_idx_random_access( n_test ) ;
+ // Boost.MultiIndex containers
+ test . boost_m_idx_multiset ( str_test ) ;
+ test . boost_m_idx_list ( str_test ) ;
+ test . boost_m_idx_random_access( str_test ) ;
+ std::cout << str_test << std::endl ;
return 0 ;
}
-
View
764 test/perform_tests.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////
//
-// Copyright Vadim Stadnik 2011-2012.
+// Copyright Vadim Stadnik 2011-2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,36 +12,92 @@
/////////////////////////////////////////////////////////////////
+#ifndef _PERFORM_TESTS_HPP
+#define _PERFORM_TESTS_HPP
+
//#pragma once
-#include <vector>
-#include <list>
-#include <set>
-#include <numeric>
-#include "timers.hpp"
-#include "test_helpers.hpp"
+// standard containers
+#include <vector>
+#include <deque>
+#include <list>
+#include <set>
+
+// boost containers
+#include <boost/container/vector.hpp>
+#include <boost/container/deque.hpp>
+#include <boost/container/list.hpp>
+#include <boost/container/set.hpp>
+#include <boost/container/flat_set.hpp>
+#include <boost/container/stable_vector.hpp>
+
+// do not link serialization library
+#define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
+//
+// "node compression" improves locality of reference and hence performance
+//#define BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES
+//
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+
+// std_ext_adv containers
#include "bp_tree_array.hpp"
#include "bp_tree_array_acc.hpp"
#include "bpt_sequence.hpp"
#include "bpt_set.hpp"
#include "bpt_map.hpp"
+//
+// dynamically allocated augmented B+ tree from project:
+// https://github.com/vstadnik/stl_ext_adv
+//
+// can be used to compare performance and effect of
+// locality of reference with array based B+ trees ;
+//
+//#include "bp_tree_idx.hpp"
+
+#include "test_helpers.hpp"
+#include "timer_chrono.hpp"
+//
+// group of simple tests for single operations of
+// container that support STL interfaces ;
+//
// example how to use the tests:
//
-// int sz_test = 100000 ;
-// std::vector<int> vector_test ;
-// test_performance::test_push_back ( sz_test , vector_test ) ;
+// std::vector<size_t> vector_szt ;
+// std::string test_result ;
+// const size_t sz_test = 1000 ;
+// test_performance::test_push_back ( sz_test , vector_szt , test_result ) ;
+// std::cout << "tests results for size = " << sz_test << " ;" <<std::endl ;
+// std::cout << test_result << std::endl ;
//
namespace test_performance
{
+ void AddTestResult
+ (
+ TimerChrono const & timer ,
+ std::string const & info ,
+ std::string & result
+ )
+ {
+ std::string str_timer ;
+ timer . TimeToString ( info , str_timer ) ;
+ result += str_timer ;
+ }
+
+
template < class _Ty_Seqce >
void test_push_back_fill
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
std::vector<size_t> vec_szt ;
@@ -52,7 +108,7 @@ namespace test_performance
std::vector<size_t>::const_iterator it_cur = vec_szt . begin ( ) ;
std::vector<size_t>::const_iterator it_end = vec_szt . end ( ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
for ( ; it_cur != it_end ; ++it_cur )
@@ -61,15 +117,16 @@ namespace test_performance
}
timer . Stop ( ) ;
- timer . PrintTime ( "push_back_fill" ) ;
+ AddTestResult ( timer , "push_back_fill" , test_res ) ;
}
template < class _Ty_Seqce >
void test_insert_fill
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
std::vector<size_t> vec_szt ;
@@ -80,21 +137,22 @@ namespace test_performance
std::vector<size_t>::const_iterator it_cur = vec_szt . begin ( ) ;
std::vector<size_t>::const_iterator it_end = vec_szt . end ( ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
seqce_test . insert ( seqce_test.end() , it_cur , it_end ) ;
timer . Stop ( ) ;
- timer . PrintTime ( "insert_fill" ) ;
+ AddTestResult ( timer , "insert_fill" , test_res ) ;
}
template < class _Ty_Seqce >
void test_clear
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
std::vector<size_t> vec_szt ;
@@ -107,21 +165,22 @@ namespace test_performance
seqce_test . insert ( seqce_test.end() , it_cur , it_end ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
seqce_test . clear ( ) ;
timer . Stop ( ) ;
- timer . PrintTime ( "test clear" ) ;
+ AddTestResult ( timer , "test clear" , test_res ) ;
}
template < class _Ty_Seqce >
void test_sort
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
std::vector<size_t> vec_szt ;
@@ -133,7 +192,7 @@ namespace test_performance
seqce_test . clear ( ) ;
seqce_test . insert ( seqce_test.end() , it_cur , it_end ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
seqce_test . sort( ) ;
@@ -142,15 +201,16 @@ namespace test_performance
// seqce_test . sort_vector( ) ;
timer . Stop ( ) ;
- timer . PrintTime ( "sort" ) ;
+ AddTestResult ( timer , "sort" , test_res ) ;
}
template < class _Ty_Seqce >
void test_unique
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
// every second element will be removed by unique()
@@ -165,21 +225,22 @@ namespace test_performance
seqce_test . insert ( seqce_test.end() , it_cur , it_end ) ;
seqce_test . sort ( ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
seqce_test . unique ( ) ;
timer . Stop ( ) ;
- timer . PrintTime ( "unique" ) ;
+ AddTestResult ( timer , "unique" , test_res ) ;
}
template < class _Ty_Seqce >
void test_reverse
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
// every second element will be removed by unique()
@@ -194,21 +255,22 @@ namespace test_performance
seqce_test . insert ( seqce_test.end() , it_cur , it_end ) ;
seqce_test . sort ( ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
seqce_test . reverse ( ) ;
timer . Stop ( ) ;
- timer . PrintTime ( "reverse" ) ;
+ AddTestResult ( timer , "reverse" , test_res ) ;
}
template < class _Ty_Seqce >
void test_remove_if
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
// every second element will be removed by unique()
@@ -225,26 +287,27 @@ namespace test_performance
test_std_ext_adv::Even<size_t>
pr_even ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
seqce_test . remove_if ( pr_even ) ;
timer . Stop ( ) ;
- timer . PrintTime ( "remove_if" ) ;
+ AddTestResult ( timer , "remove if" , test_res ) ;
}
template < class _Ty_Seqce >
void test_push_back
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
seqce_test . clear ( ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
for ( size_t i = 0 ; i < sz_test ; ++i )
@@ -253,23 +316,25 @@ namespace test_performance
}
timer . Stop ( ) ;
- timer . PrintTime ( "push_back" ) ;
+ AddTestResult ( timer , "push_back" , test_res ) ;
}
template < class _Ty_Seqce >
void test_insert_mid
(
const size_t sz_test ,
- _Ty_Seqce & seqce_test
+ _Ty_Seqce & seqce_test ,
+ std::string & test_res
)
{
seqce_test . clear ( ) ;
+ typename
_Ty_Seqce::iterator it_mid = seqce_test . begin ( ) ;
size_t count = 0 ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
for ( size_t i = 0 ; i < sz_test ; ++i )
@@ -281,7 +346,7 @@ namespace test_performance
}
timer . Stop ( ) ;
- timer . PrintTime ( "insert mid" ) ;
+ AddTestResult ( timer , "insert mid" , test_res ) ;
}
@@ -290,12 +355,13 @@ namespace test_performance
(
const size_t sz_test ,
const bool fill_rand ,
- _Ty_M_Set & m_set_test
+ _Ty_M_Set & m_set_test ,
+ std::string & test_res
)
{
m_set_test . clear ( ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
for ( size_t i = 0 ; i < sz_test ; ++i )
@@ -307,10 +373,10 @@ namespace test_performance
}
timer . Stop ( ) ;
- if ( fill_rand )
- timer . PrintTime ( "insert multiset random" ) ;
- else
- timer . PrintTime ( "insert multiset ordered" ) ;
+ std::string comment = (fill_rand) ?
+ "insert multiset random" :
+ "insert multiset ordered" ;
+ AddTestResult ( timer , comment , test_res ) ;
}
@@ -322,13 +388,14 @@ namespace test_performance
void test_insert_mid_m_set
(
const size_t sz_test ,
- _Ty_M_Set & m_set_test
+ _Ty_M_Set & m_set_test ,
+ std::string & test_res
)
{
m_set_test . clear ( ) ;
int sz = int ( sz_test ) ;
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
timer . Start ( ) ;
for ( int i = sz ; i > 0 ; --i )
@@ -341,12 +408,16 @@ namespace test_performance
}
timer . Stop ( ) ;
- timer . PrintTime ( "insert multiset mid posn" ) ;
+ AddTestResult ( timer , "insert multiset mid posn" , test_res ) ;
}
template < class _Ty_Contr >
- size_t test_accumulate_std ( _Ty_Contr const & contr_test )
+ size_t test_accumulate_std
+ (
+ _Ty_Contr const & contr_test ,
+ std::string & test_res
+ )
{
size_t res = 0 ;
size_t n_runs = 10 ;
@@ -357,10 +428,11 @@ namespace test_performance
return res ;
}
- Testing::TimerHighRes timer ;
+ TimerChrono timer ;
+ typename
_Ty_Contr::const_iterator
it_cur = contr_test . begin ( ) ,
- it_end = contr_test . begin ( ) ;
+ it_end = contr_test . begin ( ) ;
std::advance ( it_cur , int ( sz_contr / 4 ) ) ;
std::advance ( it_end , int ( sz_contr / 4 + sz_contr / 2 ) ) ;
@@ -374,13 +446,17 @@ namespace test_performance
}
timer . Stop ( ) ;
- timer . PrintTime ( "accumulate std" ) ;
+ AddTestResult ( timer , "std::accumulate" , test_res ) ;
return res ;
}
- size_t test_accumulate_fast ( const size_t sz_test )
+ size_t test_accumulate_fast
+ (
+ const size_t sz_test ,
+ std::string & test_res
+ )
{
size_t res = 0 ;
size_t n_runs = 1000 ;
@@ -391,16 +467,15 @@ namespace test_performance
_SEQCE_ACC ;
_SEQCE_ACC seqce_test ;
- test_push_back ( sz_test , seqce_test ) ;
+ test_push_back ( sz_test , seqce_test , test_res ) ;
_SEQCE_ACC::const_iterator
iter_a = seqce_test . begin ( ) ,
iter_b = seqce_test . begin ( ) ;
iter_a += int ( sz_test / 4 ) ;
iter_b += int ( sz_test / 4 + sz_test / 2 ) ;
- Testing::TimerHighRes timer ;
-
+ TimerChrono timer ;
timer . Start ( ) ;
for ( size_t i = 0 ; i < n_runs ; ++i )
@@ -409,7 +484,7 @@ namespace test_performance
}
timer . Stop ( ) ;
- timer . PrintTime ( "accumulate std" ) ;
+ AddTestResult ( timer , "fast accumulate" , test_res ) ;
return res ;
}
@@ -418,11 +493,590 @@ namespace test_performance
+//
+// methods for measurements of performance of containers
+// that support interfaces of C++ STL containers:
+// - standard containers ;
+// - containers using augmented B+ trees ;
+// - Boost containers ;
+// - Boost.MultiIndex containers ;
+//
+namespace test_performance
+{
+
+ // this test implements an algorithm that moves an iterator
+ // to a specified position and then insert a new element
+ // into a containers ;
+ //
+ // for a practical application of similar algorithms,
+ // see the classical Josephus problem
+ // http://en.wikipedia.org/wiki/Josephus_problem ;
+ //
+ // the running time of this test
+ // for all the standard and Boost containers is O ( N*N ) ;
+ // for containers using augmented data stuctures is O ( N*logN ) ;
+ //
+ template < class _Ty_Contr_Test , class _Ty_Vect_Values >
+ void advance_insert
+ (
+ _Ty_Vect_Values const & vec_value ,
+ std::vector<size_t> const & vec_dist ,
+ _Ty_Contr_Test & contr_test ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Contr_Test::value_type _Ty_Val ;
+ typedef typename _Ty_Contr_Test::iterator _Iter ;
+ typedef typename _Iter::difference_type _DistType ;
+
+ const size_t sz_test = vec_value . size ( ) ;
+
+ // insert sz_test/4 elements
+ {
+ typedef typename _Ty_Vect_Values::const_iterator _Iter_Value ;
+ typedef typename _Ty_Vect_Values::difference_type _Dist_Value ;
+ _Iter_Value iter_4 = vec_value.begin() + static_cast<_Dist_Value>(sz_test/4) ;
+ _Ty_Contr_Test contr_temp ( vec_value.begin() , iter_4 ) ;
+ contr_test = contr_temp ;
+ }
+
+
+ _Ty_Val value = _Ty_Val() ;
+ _DistType dist = 0 ;
+ _Iter iter ;
+
+ TimerChrono timer ;
+ timer . Start ( ) ;
+
+ for ( size_t i = sz_test/4 ; i < sz_test ; ++i )
+ {
+ // in this test ( i == contr_test.size() ) ;
+ dist = static_cast<_DistType>( vec_dist[i] % i ) ;
+ value = vec_value [ i ] ;
+ iter = contr_test . begin ( ) ;
+ std::advance ( iter , dist ) ;
+ contr_test . insert ( iter , value ) ;
+ }
+
+ timer . Stop ( ) ;
+
+ std::string comment ( "advance_insert();" ) ;
+ std::string str_timer ;
+ timer . TimeToString ( comment , str_timer ) ;
+ message_res += str_timer ;
+ }
+
+
+ // the test of sequential processing,
+ // its running time depends on locality
+ // of reference of input container
+ template < class _Ty_Contr , class _Ty_Val >
+ void std_accumulate
+ (
+ _Ty_Contr const & contr_test ,
+ _Ty_Val & accum_res ,
+ std::string & message_res
+ )
+ {
+ typename
+ _Ty_Contr::const_iterator
+ it_cur = contr_test . begin ( ) ,
+ it_end = contr_test . end ( ) ;
+ _Ty_Val res = _Ty_Val() ;
+ size_t n_runs = 10 ;
+
+
+ TimerChrono timer ;
+ timer . Start ( ) ;
+
+ for ( size_t i = 0 ; i < n_runs ; ++i )
+ {
+ res += std::accumulate ( it_cur , it_end , res ) ;
+ }
+ timer . Stop ( ) ;
+ std::string comment ( "accumulate();" ) ;
+ std::string str_timer ;
+ timer . TimeToString ( comment , str_timer ) ;
+ message_res += str_timer ;
+ // to compare results for different containers and
+ // to avoid compiler optimization effect
+ accum_res += res ;
+ }
+ template < class _Ty_Contr_Test , class _Ty_Vect_Values >
+ void run_tests
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ _Ty_Contr_Test & contr_test ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Contr_Test::value_type
+ _Ty_Elem ;
+ _Ty_Elem accum_res = _Ty_Elem() ;
+
+ advance_insert ( vec_values , vec_dist , contr_test , message_res ) ;
+ std_accumulate ( contr_test , accum_res , message_res ) ;
+ }
+
+
+ //
+ // standard containers
+ //
+
+ template < class _Ty_Vect_Values >
+ void std_vector
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ std::vector<_Ty_Elem> contr_x ;
+
+ message_res += ("std::vector" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+ template < class _Ty_Vect_Values >
+ void std_list
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ std::list<_Ty_Elem> contr_x ;
+
+ message_res += ("std::list" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void std_deque
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ std::deque<_Ty_Elem> contr_x ;
+
+ message_res += ("std::deque" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void std_multiset
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ std::multiset<_Ty_Elem> contr_x ;
+
+ message_res += ("std::multiset" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+
+ //
+ // containers using augmented B+ trees
+ //
+
+ template < class _Ty_Vect_Values >
+ void bpt_sequence_array
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ std_ext_adv::sequence<_Ty_Elem> contr_x ;
+
+ message_res += ("std_ext_adv::sequence_bptree_array" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+
+ template < class _Ty_Vect_Values >
+ void bpt_multiset_array
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ std_ext_adv::multiset<_Ty_Elem> contr_x ;
+
+ message_res += ("std_ext_adv::multiset_bptree_array" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ // test of dynamically allocated B+ tree "bp_tree_idx.hpp"
+// template < class _Ty_Vect_Values >
+// void bpt_sequence_list
+// (
+// _Ty_Vect_Values const & vec_values ,
+// std::vector<size_t> const & vec_dist ,
+// std::string const & elem_type ,
+// std::string & message_res
+// )
+// {
+// typedef typename _Ty_Vect_Values::value_type
+// _Ty_Elem ;
+// std_ext_adv::sequence<_Ty_Elem, std::allocator<_Ty_Elem>,
+// std_ext_adv::bp_tree_idx>
+// contr_x ;
+//
+// message_res += ("std_ext_adv::sequence_bptree_list" + elem_type + ":\n") ;
+// run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+// }
+
+
+ //
+ // Boost containers
+ //
+
+ template < class _Ty_Vect_Values >
+ void boost_vector
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ boost::container::vector<_Ty_Elem> contr_x ;
+
+ message_res += ("boost::vector" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void boost_list
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ boost::container::list<_Ty_Elem> contr_x ;
+
+ message_res += ("boost::list" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void boost_deque
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ boost::container::deque<_Ty_Elem> contr_x ;
+
+ message_res += ("boost::deque" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void boost_multiset
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ boost::container::multiset<_Ty_Elem> contr_x ;
+
+ message_res += ("boost::multiset" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void boost_stable_vector
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ boost::container::stable_vector<_Ty_Elem> contr_x ;
+
+ message_res += ("boost::stable_vector" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void boost_flat_multiset
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type _Ty_Elem ;
+ boost::container::flat_multiset<_Ty_Elem> contr_x ;
+
+ message_res += ("boost::flat_multiset" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+
+ //
+ // Boost.MultiIndex containers
+ //
+
+ using namespace boost ;
+ using namespace boost::multi_index ;
+
+ template < class _Ty_Vect_Values >
+ void boost_m_idx_multiset
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ multi_index_container<_Ty_Elem, indexed_by<ordered_non_unique<identity<_Ty_Elem> > > >
+ contr_x ;
+
+ message_res += ("boost::m_idx::multiset" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ // class adaptor to emulate std::list,
+ // for more details see Boost.MultiIndex documentation
+ template < typename T >
+ struct mutable_value
+ {
+ mutable_value ( const T & _t ) : t(_t) { }
+ operator T&() const { return t; }
+ private:
+ mutable T t ;
+ } ;
+
+ template < class _Ty_Vect_Values >
+ void boost_m_idx_list
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ // this container can be tested too
+ multi_index_container<_Ty_Elem, indexed_by<sequenced< > > >
+ // multi_index_container<mutable_value<_Ty_Elem>, indexed_by<sequenced< > > >
+ contr_x ;
+
+ message_res += ("boost::m_idx::list" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+ template < class _Ty_Vect_Values >
+ void boost_m_idx_random_access
+ (
+ _Ty_Vect_Values const & vec_values ,
+ std::vector<size_t> const & vec_dist ,
+ std::string const & elem_type ,
+ std::string & message_res
+ )
+ {
+ typedef typename _Ty_Vect_Values::value_type
+ _Ty_Elem ;
+ // this container can be tested too
+ multi_index_container<_Ty_Elem, indexed_by<random_access< > > >
+ // multi_index_container<mutable_value<_Ty_Elem>, indexed_by<random_access< > > >
+ contr_x ;
+
+ message_res += ("boost::m_idx::random_access" + elem_type + ":\n") ;
+ run_tests ( vec_values , vec_dist , contr_x , message_res ) ;
+ }
+
+} // namespace test_performance ;
+
+
+
+namespace test_performance
+{
+
+ template < class _Ty_Elem >
+ class TestContainers
+ {
+ public:
+
+ TestContainers ( std::string const & el_type ) :
+ elem_type(el_type) , values() , dist_data() { }
+
+ void InitializeData ( const size_t sz_test )
+ {
+ // test data are updated only when user changes
+ // the number of elements in a container to test
+ if ( sz_test != values.size() )
+ {
+ values . clear ( ) ;
+ for ( size_t i = 0 ; i < sz_test ; ++i )
+ values . push_back ( static_cast<_Ty_Elem>(i) ) ;
+ std::random_shuffle ( values.begin() , values.end() ) ;
+
+ dist_data . clear ( ) ;
+ test_std_ext_adv::fill_rand ( dist_data , sz_test , 1 , 1 ) ;
+ }
+ }
+
+ // standard containers
+ void std_vector ( std::string & test_res ) { test_performance::std_vector ( values , dist_data , elem_type , test_res ) ; }
+ void std_list ( std::string & test_res ) { test_performance::std_list ( values , dist_data , elem_type , test_res ) ; }
+ void std_deque ( std::string & test_res ) { test_performance::std_deque ( values , dist_data , elem_type , test_res ) ; }
+ void std_multiset ( std::string & test_res ) { test_performance::std_multiset ( values , dist_data , elem_type , test_res ) ; }
+
+ // containers using augmented B+ trees
+ void bpt_sequence_array ( std::string & test_res ) { test_performance::bpt_sequence_array ( values , dist_data , elem_type , test_res ) ; }
+ void bpt_multiset_array ( std::string & test_res ) { test_performance::bpt_multiset_array ( values , dist_data , elem_type , test_res ) ; }
+ // void bpt_sequence_list ( std::string & test_res ) { test_performance::bpt_sequence_list ( values , dist_data , elem_type , test_res ) ; }
+
+ // Boost containers
+ void boost_vector ( std::string & test_res ) { test_performance::boost_vector ( values , dist_data , elem_type , test_res ) ; }
+ void boost_list ( std::string & test_res ) { test_performance::boost_list ( values , dist_data , elem_type , test_res ) ; }
+ void boost_deque ( std::string & test_res ) { test_performance::boost_deque ( values , dist_data , elem_type , test_res ) ; }
+ void boost_multiset ( std::string & test_res ) { test_performance::boost_multiset ( values , dist_data , elem_type , test_res ) ; }
+ void boost_stable_vector ( std::string & test_res ) { test_performance::boost_stable_vector ( values , dist_data , elem_type , test_res ) ; }
+ void boost_flat_multiset ( std::string & test_res ) { test_performance::boost_flat_multiset ( values , dist_data , elem_type , test_res ) ; }
+
+ // Boost.MultiIndex containers
+ void boost_m_idx_multiset ( std::string & test_res ) { test_performance::boost_m_idx_multiset ( values , dist_data , elem_type , test_res ) ; }
+ void boost_m_idx_list ( std::string & test_res ) { test_performance::boost_m_idx_list ( values , dist_data , elem_type , test_res ) ; }
+ void boost_m_idx_random_access( std::string & test_res ) { test_performance::boost_m_idx_random_access( values , dist_data , elem_type , test_res ) ; }
+
+ private:
+ std::string elem_type ;
+ std::vector<_Ty_Elem> values ;
+ std::vector<size_t> dist_data ;
+ } ;
+
+
+ // this function can be used to test
+ // performance of a specific container
+ // that support STL interfaces
+ template < class _Ty_Elem >
+ void TestSelectedContainerType
+ (
+ std::string const & elem_type ,
+ const size_t sel_contr ,
+ const size_t sz_test ,
+ std::string & str_test_res
+ )
+ {
+ static TestContainers<_Ty_Elem> test ( elem_type ) ;
+
+ // the test data are updated only when user changes
+ // the number of elements to test
+ test . InitializeData ( sz_test ) ;
+
+ // standard containers
+ if ( sel_contr== 0 ) test.std_vector ( str_test_res ) ;
+ if ( sel_contr== 1 ) test.std_list ( str_test_res ) ;
+ if ( sel_contr== 2 ) test.std_deque ( str_test_res ) ;
+ if ( sel_contr== 3 ) test.std_multiset ( str_test_res ) ;
+ // containers using augmented B+ trees
+ if ( sel_contr== 4 ) test.bpt_sequence_array ( str_test_res ) ;
+ if ( sel_contr== 5 ) test.bpt_multiset_array ( str_test_res ) ;
+ // if ( sel_contr== 6 ) test.bpt_sequence_list ( str_test_res ) ;
+ // Boost containers
+ if ( sel_contr== 7 ) test.boost_vector ( str_test_res ) ;
+ if ( sel_contr== 8 ) test.boost_list ( str_test_res ) ;
+ if ( sel_contr== 9 ) test.boost_deque ( str_test_res ) ;
+ if ( sel_contr==10 ) test.boost_multiset ( str_test_res ) ;
+ if ( sel_contr==11 ) test.boost_stable_vector ( str_test_res ) ;
+ if ( sel_contr==12 ) test.boost_flat_multiset ( str_test_res ) ;
+ }
+//
+// example code using function TestSelectedContainerType()
+// in C++ project
+//
+// int main ( )
+// {
+// std::string str_test ;
+// const size_t selContr = 0 ;
+// const size_t selSize = 1000 ;
+//
+// std::cout << "performance test for N=" << selSize
+// << " elements;" << std::endl << std::endl ;
+//
+// test_performance::TestSelectedContainerType<size_t> ( "<size_t>" , selContr , selSize , str_test ) ;
+// test_performance::TestSelectedContainerType<double> ( "<double>" , selContr , selSize , str_test ) ;
+// std::cout << str_test << std::endl ;
+//
+// return 0 ;
+// }
+//
+// =====================================================================
+//
+// example code using function TestSelectedContainerType()
+// in Android NDK project
+//
+// JNIEXPORT jstring JNICALL Java_com_example_performancendk_PerformanceApp_TestContainer
+// (JNIEnv* env, jobject thiz, jint selContr, jint selSize, jint selElemType)
+// {
+// std::string str_test ;
+//
+// if ( selElemType == 0 ) { test_performance::TestSelectedContainerType<size_t> ( "<size_t>" , selContr , selSize , str_test ) ; }
+// else if ( selElemType == 1 ) { test_performance::TestSelectedContainerType<double> ( "<double>" , selContr , selSize , str_test ) ; }
+// else if ( selElemType == 2 ) { test_performance::TestSelectedContainerType<float> ( "<float>" , selContr , selSize , str_test ) ; }
+// else if ( selElemType == 3 ) { test_performance::TestSelectedContainerType<long> ( "<long>" , selContr , selSize , str_test ) ; }
+// else
+// {
+// str_test = "error: invalid type of element !" ;
+// }
+//
+// return env->NewStringUTF( str_test.c_str( ) ) ;
+// }
+//
+// =====================================================================
+//
+
+
+} // namespace test_performance ;
+#endif // _PERFORM_TESTS_HPP
View
13 test/timer_chrono.hpp
@@ -15,7 +15,6 @@
#ifndef _TIMER_CHRONO_HPP
#define _TIMER_CHRONO_HPP
-#include <iostream>
#include <sstream>
#include <string>
@@ -44,15 +43,6 @@ namespace test_performance
void Start ( ) { start = _clock_impl::now ( ) ; }
void Stop ( ) { stop = _clock_impl::now ( ) ; }
- void PrintTime ( std::string const & info ) const
- {
- std::string str_time ;
- TimeToString ( info , str_time ) ;
- std::cout << str_time ;
- }
-
- private:
-
double DurationMicroSec ( ) const
{
_duration durn_mcsec = stop - start ;
@@ -70,6 +60,8 @@ namespace test_performance
str_res = ostr_out . str ( ) ;
}
+ private:
+
_time_point start ;
_time_point stop ;
} ;
@@ -78,4 +70,3 @@ namespace test_performance
#endif // _TIMER_CHRONO_HPP
-

0 comments on commit edd6c22

Please sign in to comment.
Something went wrong with that request. Please try again.