profiler_map_to_unordered_map.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__
00038 #define PROFCXX_PROFILER_MAP_TO_UNORDERED_MAP_H__ 1
00039
00040 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cstdlib>
00042 #include <cstdio>
00043 #include <cstring>
00044 #else
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 #endif
00049 #include "profile/impl/profiler.h"
00050 #include "profile/impl/profiler_node.h"
00051 #include "profile/impl/profiler_trace.h"
00052
00053 namespace __gnu_profile
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 const float __map_insert_cost_factor = 1.5;
00069 const float __map_erase_cost_factor = 1.5;
00070 const float __map_find_cost_factor = 1;
00071 const float __map_iterate_cost = 2.3;
00072
00073 const float __umap_insert_cost = 12.0;
00074 const float __umap_erase_cost = 12.0;
00075 const float __umap_find_cost = 10.0;
00076 const float __umap_iterate_cost = 1.7;
00077
00078 inline int __log2(size_t __size)
00079 {
00080 for (int __bit_count = sizeof(size_t) - 1; __bit_count >= 0; --__bit_count) {
00081 if ((2 << __bit_count) & __size) {
00082 return __bit_count;
00083 }
00084 }
00085 return 0;
00086 }
00087
00088 inline float __map_insert_cost(size_t __size)
00089 {
00090 return __map_insert_cost_factor * static_cast<float>(__log2(__size));
00091 }
00092
00093 inline float __map_erase_cost(size_t __size)
00094 {
00095 return __map_erase_cost_factor * static_cast<float>(__log2(__size));
00096 }
00097
00098 inline float __map_find_cost(size_t __size)
00099 {
00100 return __map_find_cost_factor * static_cast<float>(__log2(__size));
00101 }
00102
00103
00104 class __map2umap_info: public __object_info_base
00105 {
00106 public:
00107 __map2umap_info()
00108 : _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0),
00109 _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {}
00110 __map2umap_info(__stack_t __stack)
00111 : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
00112 _M_iterate(0), _M_map_cost(0.0), _M_umap_cost(0.0), _M_valid(true) {}
00113 virtual ~__map2umap_info() {}
00114 __map2umap_info(const __map2umap_info& o);
00115 void __merge(const __map2umap_info& o);
00116 void __write(FILE* __f) const;
00117 float __magnitude() const { return _M_map_cost - _M_umap_cost; }
00118 const char* __advice() const;
00119
00120 void __record_insert(size_t __size, size_t __count);
00121 void __record_erase(size_t __size, size_t __count);
00122 void __record_find(size_t __size);
00123 void __record_iterate(size_t __count);
00124 void __record_invalidate();
00125
00126 private:
00127 size_t _M_insert;
00128 size_t _M_erase;
00129 size_t _M_find;
00130 size_t _M_iterate;
00131 float _M_umap_cost;
00132 float _M_map_cost;
00133 bool _M_valid;
00134 };
00135
00136 inline const char* __map2umap_info::__advice() const
00137 {
00138 return "change std::map to std::unordered_map";
00139 }
00140
00141 inline __map2umap_info::__map2umap_info(const __map2umap_info& __o)
00142 : __object_info_base(__o),
00143 _M_insert(__o._M_insert),
00144 _M_erase(__o._M_erase),
00145 _M_find(__o._M_find),
00146 _M_iterate(__o._M_iterate),
00147 _M_map_cost(__o._M_map_cost),
00148 _M_umap_cost(__o._M_umap_cost),
00149 _M_valid(__o._M_valid)
00150 {}
00151
00152 inline void __map2umap_info::__merge(const __map2umap_info& __o)
00153 {
00154 _M_insert += __o._M_insert;
00155 _M_erase += __o._M_erase;
00156 _M_find += __o._M_find;
00157 _M_map_cost += __o._M_map_cost;
00158 _M_umap_cost += __o._M_umap_cost;
00159 _M_valid &= __o._M_valid;
00160 }
00161
00162 inline void __map2umap_info:: __record_insert(size_t __size, size_t __count)
00163 {
00164 _M_insert += __count;
00165 _M_map_cost += __count * __map_insert_cost(__size);
00166 _M_umap_cost += __count * __umap_insert_cost;
00167 }
00168
00169 inline void __map2umap_info:: __record_erase(size_t __size, size_t __count)
00170 {
00171 _M_erase += __count;
00172 _M_map_cost += __count * __map_erase_cost(__size);
00173 _M_umap_cost += __count * __umap_erase_cost;
00174 }
00175
00176 inline void __map2umap_info:: __record_find(size_t __size)
00177 {
00178 _M_find += 1;
00179 _M_map_cost += __map_find_cost(__size);
00180 _M_umap_cost += __umap_find_cost;
00181 }
00182
00183 inline void __map2umap_info:: __record_iterate(size_t __count)
00184 {
00185 _M_iterate += __count;
00186 _M_map_cost += __count * __map_iterate_cost;
00187 _M_umap_cost += __count * __umap_iterate_cost;
00188 }
00189
00190 inline void __map2umap_info:: __record_invalidate()
00191 {
00192 _M_valid = false;
00193 }
00194
00195 inline void __map2umap_info::__write(FILE* __f) const
00196 {
00197 fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f %s\n",
00198 _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost, _M_umap_cost,
00199 _M_valid ? "valid" : "invalid");
00200 }
00201
00202
00203 class __map2umap_stack_info: public __map2umap_info
00204 {
00205 public:
00206 __map2umap_stack_info(const __map2umap_info& o) : __map2umap_info(o) {}
00207 };
00208
00209
00210 class __trace_map2umap
00211 : public __trace_base<__map2umap_info, __map2umap_stack_info>
00212 {
00213 public:
00214 __trace_map2umap();
00215 };
00216
00217 inline __trace_map2umap::__trace_map2umap()
00218 : __trace_base<__map2umap_info, __map2umap_stack_info>()
00219 {
00220 __id = "map-to-unordered-map";
00221 }
00222
00223 inline void __trace_map_to_unordered_map_init()
00224 {
00225 __tables<0>::_S_map2umap = new __trace_map2umap();
00226 }
00227
00228 inline void __trace_map_to_unordered_map_report(
00229 FILE* __f, __warning_vector_t& __warnings)
00230 {
00231 if (__tables<0>::_S_map2umap) {
00232 __tables<0>::_S_map2umap->__collect_warnings(__warnings);
00233 __tables<0>::_S_map2umap->__write(__f);
00234 }
00235 }
00236
00237
00238
00239
00240
00241 inline void __trace_map_to_unordered_map_construct(const void* __obj)
00242 {
00243 if (!__profcxx_init()) return;
00244
00245 __tables<0>::_S_map2umap->__add_object(__obj,
00246 __map2umap_info(__get_stack()));
00247 }
00248
00249 inline void __trace_map_to_unordered_map_destruct(const void* __obj)
00250 {
00251 if (!__profcxx_init()) return;
00252
00253 __tables<0>::_S_map2umap->__retire_object(__obj);
00254 }
00255
00256 inline void __trace_map_to_unordered_map_insert(const void* __obj,
00257 size_t __size, size_t __count)
00258 {
00259 if (!__profcxx_init()) return;
00260
00261 __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
00262
00263 if (__info) __info->__record_insert(__size, __count);
00264 }
00265
00266 inline void __trace_map_to_unordered_map_erase(const void* __obj,
00267 size_t __size, size_t __count)
00268 {
00269 if (!__profcxx_init()) return;
00270
00271 __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
00272
00273 if (__info) __info->__record_erase(__size, __count);
00274 }
00275
00276 inline void __trace_map_to_unordered_map_find(const void* __obj, size_t __size)
00277 {
00278 if (!__profcxx_init()) return;
00279
00280 __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
00281
00282 if (__info) __info->__record_find(__size);
00283 }
00284
00285 inline void __trace_map_to_unordered_map_iterate(const void* __obj,
00286 size_t __count)
00287 {
00288 if (!__profcxx_init()) return;
00289
00290 __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
00291
00292 if (__info) __info->__record_iterate(__count);
00293 }
00294
00295 inline void __trace_map_to_unordered_map_invalidate(const void* __obj)
00296 {
00297 if (!__profcxx_init()) return;
00298
00299 __map2umap_info* __info = __tables<0>::_S_map2umap->__get_object_info(__obj);
00300
00301 if (__info) __info->__record_invalidate();
00302 }
00303
00304 }
00305 #endif