blob: 49ee63ab6922608a3f6616f380ce2fd74f71e00a [file] [log] [blame]
Brian Silverman4a2409e2018-08-04 23:24:02 -07001
2/*
3 *
4 * (C) Copyright John Maddock 1999-2005.
5 * Use, modification and distribution are subject to the
6 * Boost Software License, Version 1.0. (See accompanying file
7 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 *
9 * This file provides some example of type_traits usage -
10 * by "optimising" various algorithms:
11 *
12 * opt::destroy_array - an example of optimisation based upon omitted destructor calls
13 *
14 */
15
16
17#include <iostream>
18#include <boost/test/included/prg_exec_monitor.hpp>
19#include <boost/timer.hpp>
20#include <boost/type_traits.hpp>
21
22using std::cout;
23using std::endl;
24using std::cin;
25
26namespace opt{
27
28//
29// algorithm destroy_array:
30// The reverse of std::unitialized_copy, takes a block of
31// initialized memory and calls destructors on all objects therein.
32//
33
34namespace detail{
35
36template <class T>
37void do_destroy_array(T* first, T* last, const boost::false_type&)
38{
39 while(first != last)
40 {
41 first->~T();
42 ++first;
43 }
44}
45
46template <class T>
47inline void do_destroy_array(T* first, T* last, const boost::true_type&)
48{
49}
50
51} // namespace detail
52
53template <class T>
54inline void destroy_array(T* p1, T* p2)
55{
56 detail::do_destroy_array(p1, p2, ::boost::has_trivial_destructor<T>());
57}
58
59//
60// unoptimised versions of destroy_array:
61//
62template <class T>
63void destroy_array1(T* first, T* last)
64{
65 while(first != last)
66 {
67 first->~T();
68 ++first;
69 }
70}
71template <class T>
72void destroy_array2(T* first, T* last)
73{
74 for(; first != last; ++first) first->~T();
75}
76
77} // namespace opt
78
79//
80// define some global data:
81//
82const int array_size = 1000;
83int i_array[array_size] = {0,};
84const int ci_array[array_size] = {0,};
85char c_array[array_size] = {0,};
86const char cc_array[array_size] = { 0,};
87
88const int iter_count = 1000000;
89
90
91int cpp_main(int argc, char* argv[])
92{
93 boost::timer t;
94 double result;
95 int i;
96 //
97 // test destroy_array,
98 // compare destruction time of an array of ints
99 // with unoptimised form.
100 //
101 cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
102 cout << "testing destroy_array...\n"
103 "[Some compilers may be able to optimise the \"unoptimised\"\n versions as well as type_traits does.]" << endl;
104
105 // cache load:
106 opt::destroy_array(i_array, i_array + array_size);
107
108 // time optimised version:
109 t.restart();
110 for(i = 0; i < iter_count; ++i)
111 {
112 opt::destroy_array(i_array, i_array + array_size);
113 }
114 result = t.elapsed();
115 cout << "destroy_array<int>: " << result << endl;
116
117 // cache load:
118 opt::destroy_array1(i_array, i_array + array_size);
119
120 // time unoptimised version #1:
121 t.restart();
122 for(i = 0; i < iter_count; ++i)
123 {
124 opt::destroy_array1(i_array, i_array + array_size);
125 }
126 result = t.elapsed();
127 cout << "destroy_array<int>(unoptimised#1): " << result << endl;
128
129 // cache load:
130 opt::destroy_array2(i_array, i_array + array_size);
131
132 // time unoptimised version #2:
133 t.restart();
134 for(i = 0; i < iter_count; ++i)
135 {
136 opt::destroy_array2(i_array, i_array + array_size);
137 }
138 result = t.elapsed();
139 cout << "destroy_array<int>(unoptimised#2): " << result << endl << endl;
140
141 return 0;
142}
143
144
145
146
147
148
149
150
151
152
153