fork(1) download
  1. // Synthetic speed comparison of "virtual", "switch", "if-else O(N)", "if-else O(logN)" and "static".
  2. // Tests are done for different "types" count (i.e. "case branches" or count of derived classes, etc).
  3. // NOTE: try different settings: MAX_TYPES_COUNT, N, try to play with compiler optimization options,
  4. // process affinity mask, etc
  5. // NOTE: Calculations are simple, in "static" case they can be very efficently optimized (folded).
  6. // Author: Evgeny Panasyuk
  7.  
  8. #include <algorithm>
  9. #include <iostream>
  10. #include <iomanip>
  11. #include <vector>
  12. #include <ios>
  13.  
  14. #include <boost/ptr_container/ptr_vector.hpp>
  15. #include <boost/preprocessor/repetition.hpp>
  16. #include <boost/range/iterator_range.hpp>
  17. #include <boost/mpl/for_each.hpp>
  18. #include <boost/mpl/list.hpp>
  19. #include <boost/config/suffix.hpp>
  20. #include <boost/timer.hpp>
  21. #include <boost/foreach.hpp>
  22.  
  23. template<int types_cnt> struct dispatch_base_shuffle_indexed;
  24. template<int types_cnt> struct dispatch_base_regular;
  25.  
  26. //------------------------------Settings---------------------------------
  27.  
  28. #define IDEONE_DOT_COM // Comment this line - it is only for ideone.com
  29.  
  30.  
  31. // Max types count. Tests will be done for 1 to MAX_TYPES_COUNT types
  32. #define MAX_TYPES_COUNT 128
  33.  
  34. // Work amount for one test
  35. const int N=100000;//100000
  36.  
  37. // Outter loop iterations
  38. const int OUTER_ITERS=16;
  39.  
  40. template<int T>
  41. struct dispatch_base
  42. {
  43. // Select one of indexing type below:
  44.  
  45. typedef dispatch_base_shuffle_indexed<T> type;
  46. //typedef dispatch_base_regular<T> type;
  47. };
  48.  
  49. //------------------------------Common stuff-----------------------------
  50.  
  51. #ifdef IDEONE_DOT_COM
  52. #undef BOOST_FORCEINLINE
  53. #define BOOST_FORCEINLINE inline __attribute__ ((always_inline))
  54. #undef MAX_TYPES_COUNT
  55. #define MAX_TYPES_COUNT 64
  56. #else
  57. #include <boost/range/algorithm/random_shuffle.hpp>
  58. #endif
  59.  
  60. struct dispatch_data
  61. {
  62. double elapsed;
  63. int result;
  64. const char *name;
  65. };
  66.  
  67. template<class T,int types_cnt,int iters_cnt=(MAX_TYPES_COUNT*N/types_cnt)>
  68. struct dispatch: public T
  69. {
  70. void do_test()
  71. {
  72. data.result=0;
  73. this->init();
  74. boost::timer t;
  75. for (int i = 0; i !=iters_cnt; ++i)
  76. {
  77. data.result+=this->iter(i);
  78. }
  79. data.elapsed = t.elapsed();
  80. data.name=this->get_name();
  81. }
  82. dispatch_data data;
  83. static const int types_count=types_cnt;
  84. static const int iterations_cnt=iters_cnt;
  85. };
  86.  
  87. template<template<int>class T,int types_cnt>
  88. struct dispatch_m
  89. {
  90. typedef dispatch<T<types_cnt>,types_cnt> type;
  91. };
  92.  
  93. template<int types_cnt>
  94. struct dispatch_base_regular
  95. {
  96. BOOST_FORCEINLINE int get_type_t(int i)
  97. {
  98. return i;
  99. }
  100. };
  101.  
  102. template<int types_cnt>
  103. struct dispatch_base_shuffle_indexed
  104. {
  105. typedef std::vector<int> index_vector_t;
  106. dispatch_base_shuffle_indexed(): current_i(0)
  107. {
  108. for(int d=0;d!=deck_count;++d)
  109. {
  110. for(int i=0;i!=types_cnt;++i)
  111. {
  112. index.push_back(i);
  113. }
  114. #ifndef IDEONE_DOT_COM
  115. boost::random_shuffle(boost::iterator_range<index_vector_t::iterator>(index.begin()+d*types_cnt,index.begin()+(d+1)*types_cnt));
  116. #else
  117. std::random_shuffle(index.begin()+d*types_cnt,index.begin()+(d+1)*types_cnt);
  118. #endif
  119. }
  120. }
  121. BOOST_FORCEINLINE int get_type_t(int i)
  122. {
  123. return index[(current_i++)%index.size()];
  124. }
  125. private:
  126. static const int deck_count=128;
  127. index_vector_t index;
  128. int current_i;
  129. };
  130.  
  131. template<int types_cnt,template<int,int>class T>
  132. struct branch_dispatch_base: protected dispatch_base<types_cnt>::type
  133. {
  134. protected:
  135. std::vector<int> v;
  136. public:
  137. void init()
  138. {
  139. for (int i = 0; i != types_cnt; ++i)
  140. {
  141. v.push_back(i);
  142. }
  143. }
  144. BOOST_FORCEINLINE int iter(int i)
  145. {
  146. int result=0;
  147. for(int t=0;t!=types_cnt;++t)
  148. {
  149. result+=T<types_cnt,types_cnt>::call(v[this->get_type_t(t)],i);
  150. }
  151. return result;
  152. }
  153. };
  154.  
  155. #define CALC (x+p)
  156.  
  157. //------------------------Stuff for "switch" test------------------------
  158. template<int p>
  159. BOOST_FORCEINLINE int func(int x)
  160. {
  161. return CALC;
  162. };
  163.  
  164. #define CASE_MACRO(z, p, unused) case p:return func<p>(i);
  165.  
  166. template<int p,int>
  167. struct test_switch;
  168.  
  169. #define SWITCH_FUNCS(z, p, unused) \
  170. template<int types_cnt> \
  171. struct test_switch<p+1,types_cnt> \
  172. { \
  173.   BOOST_FORCEINLINE static int call(int x,int i) \
  174.   { \
  175.   switch(x) \
  176.   { \
  177.   BOOST_PP_REPEAT(BOOST_PP_ADD(p,1), CASE_MACRO, ~) \
  178.   default:return -1; \
  179.   } \
  180.   } \
  181. };
  182.  
  183. BOOST_PP_REPEAT(MAX_TYPES_COUNT, SWITCH_FUNCS, ~)
  184.  
  185. template<int types_cnt>
  186. struct switch_dispatch: public branch_dispatch_base<types_cnt,test_switch>
  187. {
  188. static const char * const get_name()
  189. {
  190. return "switch";
  191. };
  192. };
  193.  
  194. //----------------------------Stuff for "if-else O(N)"-------------------
  195.  
  196. template<int p,int types_cnt>
  197. struct test_ifelse_on
  198. {
  199. BOOST_FORCEINLINE static int call(int x,int i)
  200. {
  201. if(x==(types_cnt-p))
  202. return func<types_cnt-p>(i);
  203. return test_ifelse_on<p-1,types_cnt>::call(x,i);
  204. }
  205. };
  206.  
  207. template<int types_cnt>
  208. struct test_ifelse_on<0,types_cnt>
  209. {
  210. BOOST_FORCEINLINE static int call(int x,int i)
  211. {
  212. return -1;
  213. }
  214. };
  215.  
  216. template<int types_cnt>
  217. struct ifelse_on_dispatch: public branch_dispatch_base<types_cnt,test_ifelse_on>
  218. {
  219. static const char * const get_name()
  220. {
  221. return "if-else_O(N)";
  222. };
  223. };
  224.  
  225. //----------------------Stuff for "if-else O(logN)"----------------------
  226. template<int lower,int upper/*,int level*/>
  227. struct test_ifelse_ologn
  228. {
  229. BOOST_FORCEINLINE static int call(int x,int i)
  230. {
  231. const int middle=(lower+upper)/2;
  232. if(x>middle)
  233. return test_ifelse_ologn<middle+1,upper/*,level-1*/>::call(x,i);
  234. else
  235. return test_ifelse_ologn<lower,middle/*,level-1*/>::call(x,i);
  236. }
  237. };
  238.  
  239. template<int lower>
  240. struct test_ifelse_ologn<lower,lower>
  241. {
  242. BOOST_FORCEINLINE static int call(int x,int i)
  243. {
  244. return lower+i;
  245. }
  246. };
  247.  
  248. template<int types_cnt,int>
  249. struct test_ifelse_ologn_m: public test_ifelse_ologn<0,types_cnt-1>
  250. {
  251. };
  252.  
  253. template<int types_cnt>
  254. struct ifelse_ologn_dispatch: public branch_dispatch_base<types_cnt,test_ifelse_ologn_m>
  255. {
  256. static const char * const get_name()
  257. {
  258. return "if-else_O(log(N))";
  259. };
  260. };
  261.  
  262. //---------------------Stuff for "virtual" call test---------------------
  263. struct base
  264. {
  265. virtual int call(int x)=0;
  266. };
  267.  
  268. template<int p>
  269. class derived: public base
  270. {
  271. virtual int call(int x)
  272. {
  273. return CALC;
  274. };
  275. };
  276.  
  277. template<int p>
  278. struct fill_vector
  279. {
  280. static void f(boost::ptr_vector<base> &v)
  281. {
  282. fill_vector<p-1>::f(v);
  283. v.push_back(new derived<p-1>());
  284. }
  285. };
  286.  
  287. template<>
  288. struct fill_vector<0>
  289. {
  290. static void f(boost::ptr_vector<base> &v) {}
  291. };
  292.  
  293. template<int types_cnt>
  294. struct virtual_dispatch: protected dispatch_base<types_cnt>::type
  295. {
  296. void init()
  297. {
  298. fill_vector<types_cnt>::f(v);
  299. }
  300. BOOST_FORCEINLINE int iter(int i)
  301. {
  302. int result=0;
  303. for(int t=0;t!=types_cnt;++t)
  304. {
  305. result+=v[this->get_type_t(t)].call(i);
  306. }
  307. return result;
  308. }
  309. static const char * const get_name()
  310. {
  311. return "virtual";
  312. };
  313. private:
  314. boost::ptr_vector<base> v;
  315. };
  316.  
  317. //---------------------Stuff for "static" call test----------------------
  318.  
  319. // It is possible to omit this struct, it just for "emulate" policies
  320. // (for cases when compiler can't do good optimizations)
  321. template<class T>
  322. struct static_call: public T
  323. {
  324. };
  325.  
  326. template<int p>
  327. struct static_call_policy
  328. {
  329. static BOOST_FORCEINLINE int static_func(int x)
  330. {
  331. return static_call_policy<p-1>::static_func(x)+CALC;
  332. };
  333. };
  334.  
  335. template<>
  336. struct static_call_policy<0>
  337. {
  338. static BOOST_FORCEINLINE int static_func(int x)
  339. {
  340. return x;
  341. };
  342. };
  343.  
  344. template<int types_cnt>
  345. struct static_dispatch
  346. {
  347. void init() {}
  348. BOOST_FORCEINLINE int iter(int i)
  349. {
  350. return static_call< static_call_policy<types_cnt-1> >::static_func(i);
  351. }
  352. static const char * const get_name()
  353. {
  354. return "static";
  355. };
  356. };
  357. //-----------------------------Testing stuff-----------------------------
  358.  
  359. template<int types_cnt>
  360. struct dispatchers_t
  361. {
  362. typedef boost::mpl::list
  363. <
  364. typename dispatch_m<static_dispatch,types_cnt>::type,
  365. typename dispatch_m<switch_dispatch,types_cnt>::type,
  366. typename dispatch_m<virtual_dispatch,types_cnt>::type,
  367. typename dispatch_m<ifelse_ologn_dispatch,types_cnt>::type,
  368. typename dispatch_m<ifelse_on_dispatch,types_cnt>::type
  369. > type;
  370. };
  371.  
  372. struct test_elapsed
  373. {
  374. template<class D>
  375. void operator()(D &d)
  376. {
  377. d.do_test();
  378. if((results.size()>0)&&(results[0].result!=d.data.result))
  379. {
  380. std::cerr << "results do not match" << std::endl;
  381. }
  382. std::cout << "\t" << d.data.name << " elapsed=" << (1.0e9*d.data.elapsed/(d.iterations_cnt*d.types_count)) /*<< " result=" << d.data.result*/ << std::endl;
  383. BOOST_FOREACH( dispatch_data data, results )
  384. {
  385. std::cout << "\t\t" << d.data.name << "/" << data.name << "=" << d.data.elapsed/data.elapsed << "x (elapsed)" << std::endl;
  386. }
  387. results.push_back(d.data);
  388. }
  389. std::vector<dispatch_data> results;
  390. };
  391.  
  392. template<int types_cnt>
  393. struct do_tests
  394. {
  395. static void f()
  396. {
  397. do_tests<types_cnt-1>::f();
  398. std::cout << "Types count=" << types_cnt << std::endl;
  399. std::cout << "\tTypes count=" << types_cnt << std::endl;
  400. boost::mpl::for_each<typename dispatchers_t<types_cnt>::type>(test_elapsed());
  401. std::cout << std::endl;
  402. }
  403. };
  404.  
  405. template<>
  406. struct do_tests<0>
  407. {
  408. static void f() {}
  409. };
  410.  
  411. //-----------------------------------------------------------------------
  412. int main(int argc,char **argv)
  413. {
  414. std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
  415. //std::cout.precision(3);
  416. for(int i=0;i!=OUTER_ITERS;++i)
  417. {
  418. std::cout << "I=" << i << std::endl;
  419. do_tests<MAX_TYPES_COUNT>::f();
  420. }
  421. }
  422.  
  423.  
Time limit exceeded #stdin #stdout 15s 3344KB
stdin
Standard input is empty
stdout
I=0
Types count=1
	Types count=1
	static elapsed=0.000000
	switch elapsed=20.312500
		switch/static=infx (elapsed)
	virtual elapsed=28.125000
		virtual/static=infx (elapsed)
		virtual/switch=1.384615x (elapsed)
	if-else_O(log(N)) elapsed=3.125000
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.153846x (elapsed)
		if-else_O(log(N))/virtual=0.111111x (elapsed)
	if-else_O(N) elapsed=18.750000
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=0.923077x (elapsed)
		if-else_O(N)/virtual=0.666667x (elapsed)
		if-else_O(N)/if-else_O(log(N))=6.000000x (elapsed)

Types count=2
	Types count=2
	static elapsed=1.562500
	switch elapsed=21.875000
		switch/static=14.000000x (elapsed)
	virtual elapsed=32.812500
		virtual/static=21.000000x (elapsed)
		virtual/switch=1.500000x (elapsed)
	if-else_O(log(N)) elapsed=20.312500
		if-else_O(log(N))/static=13.000000x (elapsed)
		if-else_O(log(N))/switch=0.928571x (elapsed)
		if-else_O(log(N))/virtual=0.619048x (elapsed)
	if-else_O(N) elapsed=21.875000
		if-else_O(N)/static=14.000000x (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.666667x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.076923x (elapsed)

Types count=3
	Types count=3
	static elapsed=0.000000
	switch elapsed=23.437504
		switch/static=infx (elapsed)
	virtual elapsed=31.250005
		virtual/static=infx (elapsed)
		virtual/switch=1.333333x (elapsed)
	if-else_O(log(N)) elapsed=21.875003
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.933333x (elapsed)
		if-else_O(log(N))/virtual=0.700000x (elapsed)
	if-else_O(N) elapsed=23.437504
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.750000x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.071429x (elapsed)

Types count=4
	Types count=4
	static elapsed=0.000000
	switch elapsed=23.437500
		switch/static=infx (elapsed)
	virtual elapsed=35.937500
		virtual/static=infx (elapsed)
		virtual/switch=1.533333x (elapsed)
	if-else_O(log(N)) elapsed=21.875000
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.933333x (elapsed)
		if-else_O(log(N))/virtual=0.608696x (elapsed)
	if-else_O(N) elapsed=23.437500
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.652174x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.071429x (elapsed)

Types count=5
	Types count=5
	static elapsed=0.000000
	switch elapsed=29.687500
		switch/static=infx (elapsed)
	virtual elapsed=34.375000
		virtual/static=infx (elapsed)
		virtual/switch=1.157895x (elapsed)
	if-else_O(log(N)) elapsed=23.437500
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.789474x (elapsed)
		if-else_O(log(N))/virtual=0.681818x (elapsed)
	if-else_O(N) elapsed=25.000000
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=0.842105x (elapsed)
		if-else_O(N)/virtual=0.727273x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.066667x (elapsed)

Types count=6
	Types count=6
	static elapsed=0.000000
	switch elapsed=28.125018
		switch/static=infx (elapsed)
	virtual elapsed=35.937522
		virtual/static=infx (elapsed)
		virtual/switch=1.277778x (elapsed)
	if-else_O(log(N)) elapsed=23.437515
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.833333x (elapsed)
		if-else_O(log(N))/virtual=0.652174x (elapsed)
	if-else_O(N) elapsed=28.125018
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.782609x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.200000x (elapsed)

Types count=7
	Types count=7
	static elapsed=0.000000
	switch elapsed=28.125022
		switch/static=infx (elapsed)
	virtual elapsed=35.937528
		virtual/static=infx (elapsed)
		virtual/switch=1.277778x (elapsed)
	if-else_O(log(N)) elapsed=25.000020
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.888889x (elapsed)
		if-else_O(log(N))/virtual=0.695652x (elapsed)
	if-else_O(N) elapsed=28.125022
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.782609x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.125000x (elapsed)

Types count=8
	Types count=8
	static elapsed=0.000000
	switch elapsed=29.687500
		switch/static=infx (elapsed)
	virtual elapsed=29.687500
		virtual/static=infx (elapsed)
		virtual/switch=1.000000x (elapsed)
	if-else_O(log(N)) elapsed=25.000000
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.842105x (elapsed)
		if-else_O(log(N))/virtual=0.842105x (elapsed)
	if-else_O(N) elapsed=29.687500
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=1.000000x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.187500x (elapsed)

Types count=9
	Types count=9
	static elapsed=0.000000
	switch elapsed=28.125004
		switch/static=infx (elapsed)
	virtual elapsed=31.250005
		virtual/static=infx (elapsed)
		virtual/switch=1.111111x (elapsed)
	if-else_O(log(N)) elapsed=26.562504
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.944444x (elapsed)
		if-else_O(log(N))/virtual=0.850000x (elapsed)
	if-else_O(N) elapsed=29.687505
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.055556x (elapsed)
		if-else_O(N)/virtual=0.950000x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.117647x (elapsed)

Types count=10
	Types count=10
	static elapsed=0.000000
	switch elapsed=29.687500
		switch/static=infx (elapsed)
	virtual elapsed=31.250000
		virtual/static=infx (elapsed)
		virtual/switch=1.052632x (elapsed)
	if-else_O(log(N)) elapsed=25.000000
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.842105x (elapsed)
		if-else_O(log(N))/virtual=0.800000x (elapsed)
	if-else_O(N) elapsed=29.687500
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.950000x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.187500x (elapsed)

Types count=11
	Types count=11
	static elapsed=0.000000
	switch elapsed=28.125009
		switch/static=infx (elapsed)
	virtual elapsed=31.250010
		virtual/static=infx (elapsed)
		virtual/switch=1.111111x (elapsed)
	if-else_O(log(N)) elapsed=26.562508
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.944444x (elapsed)
		if-else_O(log(N))/virtual=0.850000x (elapsed)
	if-else_O(N) elapsed=31.250010
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.111111x (elapsed)
		if-else_O(N)/virtual=1.000000x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.176471x (elapsed)

Types count=12
	Types count=12
	static elapsed=0.000000
	switch elapsed=28.125018
		switch/static=infx (elapsed)
	virtual elapsed=31.250020
		virtual/static=infx (elapsed)
		virtual/switch=1.111111x (elapsed)
	if-else_O(log(N)) elapsed=26.562517
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.944444x (elapsed)
		if-else_O(log(N))/virtual=0.850000x (elapsed)
	if-else_O(N) elapsed=31.250020
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.111111x (elapsed)
		if-else_O(N)/virtual=1.000000x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.176471x (elapsed)

Types count=13
	Types count=13
	static elapsed=0.000000
	switch elapsed=28.125040
		switch/static=infx (elapsed)
	virtual elapsed=32.812546
		virtual/static=infx (elapsed)
		virtual/switch=1.166667x (elapsed)
	if-else_O(log(N)) elapsed=28.125040
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.000000x (elapsed)
		if-else_O(log(N))/virtual=0.857143x (elapsed)
	if-else_O(N) elapsed=31.250044
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.111111x (elapsed)
		if-else_O(N)/virtual=0.952381x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.111111x (elapsed)

Types count=14
	Types count=14
	static elapsed=0.000000
	switch elapsed=28.125053
		switch/static=infx (elapsed)
	virtual elapsed=32.812562
		virtual/static=infx (elapsed)
		virtual/switch=1.166667x (elapsed)
	if-else_O(log(N)) elapsed=28.125053
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.000000x (elapsed)
		if-else_O(log(N))/virtual=0.857143x (elapsed)
	if-else_O(N) elapsed=31.250059
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.111111x (elapsed)
		if-else_O(N)/virtual=0.952381x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.111111x (elapsed)

Types count=15
	Types count=15
	static elapsed=0.000000
	switch elapsed=31.250049
		switch/static=infx (elapsed)
	virtual elapsed=35.937556
		virtual/static=infx (elapsed)
		virtual/switch=1.150000x (elapsed)
	if-else_O(log(N)) elapsed=28.125044
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=0.900000x (elapsed)
		if-else_O(log(N))/virtual=0.782609x (elapsed)
	if-else_O(N) elapsed=31.250049
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.000000x (elapsed)
		if-else_O(N)/virtual=0.869565x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.111111x (elapsed)

Types count=16
	Types count=16
	static elapsed=0.000000
	switch elapsed=29.687500
		switch/static=infx (elapsed)
	virtual elapsed=37.500000
		virtual/static=infx (elapsed)
		virtual/switch=1.263158x (elapsed)
	if-else_O(log(N)) elapsed=29.687500
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.000000x (elapsed)
		if-else_O(log(N))/virtual=0.791667x (elapsed)
	if-else_O(N) elapsed=31.250000
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.052632x (elapsed)
		if-else_O(N)/virtual=0.833333x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.052632x (elapsed)

Types count=17
	Types count=17
	static elapsed=0.000000
	switch elapsed=29.687546
		switch/static=infx (elapsed)
	virtual elapsed=37.500059
		virtual/static=infx (elapsed)
		virtual/switch=1.263158x (elapsed)
	if-else_O(log(N)) elapsed=29.687546
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.000000x (elapsed)
		if-else_O(log(N))/virtual=0.791667x (elapsed)
	if-else_O(N) elapsed=31.250049
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.052632x (elapsed)
		if-else_O(N)/virtual=0.833333x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.052632x (elapsed)

Types count=18
	Types count=18
	static elapsed=0.000000
	switch elapsed=29.687546
		switch/static=infx (elapsed)
	virtual elapsed=35.937556
		virtual/static=infx (elapsed)
		virtual/switch=1.210526x (elapsed)
	if-else_O(log(N)) elapsed=29.687546
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.000000x (elapsed)
		if-else_O(log(N))/virtual=0.826087x (elapsed)
	if-else_O(N) elapsed=31.250049
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.052632x (elapsed)
		if-else_O(N)/virtual=0.869565x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.052632x (elapsed)

Types count=19
	Types count=19
	static elapsed=0.000000
	switch elapsed=29.687509
		switch/static=infx (elapsed)
	virtual elapsed=35.937511
		virtual/static=infx (elapsed)
		virtual/switch=1.210526x (elapsed)
	if-else_O(log(N)) elapsed=31.250010
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.052632x (elapsed)
		if-else_O(log(N))/virtual=0.869565x (elapsed)
	if-else_O(N) elapsed=31.250010
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.052632x (elapsed)
		if-else_O(N)/virtual=0.869565x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.000000x (elapsed)

Types count=20
	Types count=20
	static elapsed=0.000000
	switch elapsed=29.687500
		switch/static=infx (elapsed)
	virtual elapsed=35.937500
		virtual/static=infx (elapsed)
		virtual/switch=1.210526x (elapsed)
	if-else_O(log(N)) elapsed=31.250000
		if-else_O(log(N))/static=infx (elapsed)
		if-else_O(log(N))/switch=1.052632x (elapsed)
		if-else_O(log(N))/virtual=0.869565x (elapsed)
	if-else_O(N) elapsed=31.250000
		if-else_O(N)/static=infx (elapsed)
		if-else_O(N)/switch=1.052632x (elapsed)
		if-else_O(N)/virtual=0.869565x (elapsed)
		if-else_O(N)/if-else_O(log(N))=1.000000x (elapsed)

Types count=21
	Types count=21
	static elapsed=0.000000