language: C++11 (gcc-4.7.2)
date: 501 days 13 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#ifndef ASSOCIATIVE_H
#define ASSOCIATIVE_H
#pragma once
#include <algorithm>
#include <cassert>
#include <functional>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include <vector>
 
template<class iterator> inline auto structure_dereference_operator(const iterator& r) -> typename std::iterator_traits<iterator>::pointer {return r.operator->();}
template<class type> inline typename std::iterator_traits<type*>::pointer structure_dereference_operator(const type*& r) {return r;}
 
#pragma warning(push)
#pragma warning(disable : 4820)  //warning C4820: 'associative<key_,mapped_>' : '3' bytes padding added after data member 'associative<key_,mapped_>::comp_'
//http://msdn.microsoft.com/en-us/library/xdayte4c.aspx
// carefully designed to also work on a linked list.  Not that you should, because that would be silly.
template <class key_, 
          class mapped_, 
          class traits_ = std::less<key_>,
                  class undertype_ = std::vector<std::pair<key_,mapped_> >
         >
class associative
{
public:
        typedef traits_ key_compare;
        typedef key_ key_type;
        typedef mapped_ mapped_type;
        typedef std::pair<const key_type, mapped_type> value_type;
        typedef typename undertype_::allocator_type allocator_type;
        typedef typename allocator_type::template rebind<value_type>::other value_allocator_type;
        typedef typename undertype_::const_iterator const_iterator;
        typedef typename value_allocator_type::const_pointer const_pointer;
        typedef typename value_allocator_type::const_reference const_reference;
        typedef typename undertype_::const_reverse_iterator const_reverse_iterator;
        typedef typename value_allocator_type::difference_type difference_type;
        typedef typename value_allocator_type::pointer pointer;
        typedef typename value_allocator_type::reference reference;
        typedef typename undertype_::size_type size_type;
        typedef typename undertype_::iterator underiter;
        typedef typename undertype_::const_iterator underciter;
        typedef typename undertype_::reverse_iterator underriter;
        typedef std::pair<key_type, mapped_type> undertype;
        static_assert(std::is_same<typename undertype_::value_type, undertype >::value, "container::value_type must be std::pair<key_,mapped_>");
        static_assert(std::is_same<typename undertype_::reference, typename allocator_type::reference>::value, "container::reference must be allocator_type::reference");
        static_assert(std::is_same<typename undertype_::pointer, typename allocator_type::pointer>::value, "container::pointer must be allocator_type::pointer");
        class value_compare {
                key_compare pred_;
        public:
                inline value_compare(key_compare pred=key_compare()) : pred_(pred) {}
        template <typename L, typename R>
        inline bool operator()(const L& left, const R& right) const { return pred_(left.first,right.first); }
        template <typename L>
        inline bool operator()(const L& left, const key_type& right) const { return pred_(left.first,right); }
        template <typename R>
        inline bool operator()(const key_type& left, const R& right) const { return pred_(left,right.first); }
        inline bool operator()(const key_type& left, const key_type& right) const { return pred_(left,right); }
                inline key_compare key_comp( ) const {return pred_;}
        };
        class iterator  {
        public:       
                friend class associative<key_,mapped_,traits_,undertype_>;
 
                typedef typename value_allocator_type::difference_type difference_type;
                typedef typename value_allocator_type::value_type value_type;
                typedef typename value_allocator_type::reference reference;
                typedef typename value_allocator_type::pointer pointer;
                typedef std::bidirectional_iterator_tag iterator_category;
 
                inline iterator() : data() {}
                inline iterator(const iterator& rhs) : data(rhs.data) {}
                inline iterator& operator=(const iterator& rhs) {data=rhs.data; return *this;}
                inline bool operator==(const iterator& rhs) const {return data==rhs.data;}
                inline bool operator!=(const iterator& rhs) const {return data!=rhs.data;} 
                inline iterator& operator++() {++data; return *this;}
                inline iterator operator++(int) {return iterator(data++);}
                inline iterator& operator--() {--data; return *this;}
                inline iterator operator--(int) {return iterator(data--);}
                inline reference operator*() const { return reinterpret_cast<reference>(*data);} //cant const_cast half of a pair
                inline pointer operator->() const {return reinterpret_cast<pointer>(structure_dereference_operator(data));} //cant const_cast half of a pair
                inline operator const_iterator&() {return data;}
        protected:
                explicit inline iterator(const underiter& rhs) : data(rhs) {}
                underiter data;
        };
        class reverse_iterator  {
        public:       
                friend class associative<key_,mapped_,traits_,undertype_>;
 
                typedef typename value_allocator_type::difference_type difference_type;
                typedef typename value_allocator_type::value_type value_type;
                typedef typename value_allocator_type::reference reference;
                typedef typename value_allocator_type::pointer pointer;
                typedef std::bidirectional_iterator_tag iterator_category;
 
                inline reverse_iterator() : data() {}
                inline reverse_iterator(const reverse_iterator& rhs) : data(rhs.data) {}
                inline reverse_iterator& operator=(const reverse_iterator& rhs) {data=rhs.data; return *this;}
                inline bool operator==(const reverse_iterator& rhs) const {return data==rhs.data;}
                inline bool operator!=(const reverse_iterator& rhs) const {return data!=rhs.data;} 
                inline reverse_iterator& operator++() {++data; return *this;}
                inline reverse_iterator operator++(int) {return reverse_iterator(data++);}
                inline reverse_iterator& operator--() {--data; return *this;}
                inline reverse_iterator operator--(int) {return reverse_iterator(data--);}
                inline reference operator*() const { return reinterpret_cast<reference>(*data);} //cant const_cast half of a pair
                inline pointer operator->() const {return reinterpret_cast<pointer>(structure_dereference_operator(data));} //cant const_cast half of a pair
                inline operator underriter&() {return data;}
        protected:
                explicit inline reverse_iterator(const underriter& rhs) : data(rhs) {}
                underriter data;
        };
 
        inline associative() : internal_(), comp_() {}
        explicit associative(const key_compare& traits) : internal_(), comp_(traits) {}
    inline associative(const key_compare& traits, const allocator_type& allocator) :internal_(allocator), comp_(traits) {}
    inline associative(const associative& rhs) : internal_(rhs.internal_), comp_(rhs.comp_) {}
    inline associative(associative&& rhs) : internal_(std::move(rhs.internal_)), comp_(std::move(rhs.comp_)) {}
    template<class input_iterator>
    inline associative(input_iterator first, input_iterator last) : internal_(first, last), comp_() 
        {if (std::is_sorted(internal_.begin(), internal_.end())==false) std::sort(internal_.begin(), internal_.end(), comp_);}
    template<class input_iterator>
    inline associative(input_iterator first, input_iterator last, const key_compare& traits) : internal_(first, last, traits), comp_(traits) 
        {if (std::is_sorted(internal_.begin(), internal_.end())==false) std::sort(internal_.begin(), internal_.end(), comp_);}
    template<class input_iterator>
    inline associative(input_iterator first, input_iterator last, const key_compare& traits, const allocator_type& allocator) : internal_(first, last, allocator), comp_(traits) 
        {if (std::is_sorted(internal_.begin(), internal_.end())==false) std::sort(internal_.begin(), internal_.end(), comp_);}
        inline ~associative() {}
 
        //TODO assign from different underlying type
        inline associative& operator=(const associative& right){internal_=right.internal_; comp_=right.comp_; return *this;}
    inline associative& operator=(associative&& right){internal_=std::move(right.internal_); comp_=std::move(right.comp_); return *this;}
        inline const_iterator begin() const {return internal_.begin();}
    inline iterator begin() {return iterator(internal_.begin());}
        inline const_iterator cbegin() const {return internal_.cbegin();}
    inline const_iterator end() const {return internal_.end();}
    inline iterator end() {return iterator(internal_.end());}
        inline const_iterator cend() const {return internal_.cend();} 
    inline const_reverse_iterator rbegin() const {return internal_.rbegin();}
    inline reverse_iterator rbegin() {return reverse_iterator(internal_.rbegin());}
        inline const_reverse_iterator crbegin() const {return internal_.crbegin();} 
    inline const_reverse_iterator rend() const {return internal_.rend();}  
    inline reverse_iterator rend() {return reverse_iterator(internal_.rend());}  
        inline const_reverse_iterator crend() const {return internal_.crend();}  
        inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const {return std::equal_range(internal_.begin(), internal_.end(), key, comp_);}
    inline std::pair<iterator, iterator> equal_range(const key_type& key) {
                auto i = std::equal_range(internal_.begin(), internal_.end(), key, comp_);
                return std::pair<iterator, iterator>(iterator(i.first), iterator(i.second));
        }
        inline iterator lower_bound(const key_type& key) {return iterator(std::lower_bound(internal_.begin(), internal_.end(), key, comp_));}
    inline const_iterator lower_bound(const key_type& key) const {return std::lower_bound(internal_.begin(), internal_.end(), key, comp_);}
        inline iterator upper_bound(const key_type& key) {return iterator(std::upper_bound(internal_.begin(), internal_.end(), key, comp_));}
    inline const_iterator upper_bound(const key_type& key) const {return std::upper_bound(internal_.begin(), internal_.end(), key, comp_);}
 
        inline mapped_type& at(const key_type& key) {
                underiter i = std::lower_bound(internal_.begin(), internal_.end(), key, comp_);
                if (i==internal_.end() || comp_(key,*i))
                        throw std::out_of_range("invalid associative<K, T> key");
                return i->second;
        }
    inline const mapped_type& at(const key_type& key) const {
                underciter i = std::lower_bound(internal_.begin(), internal_.end(), key, comp_);
                if (i==internal_.end() || comp_(key,*i))
                        throw std::out_of_range("invalid associative<K, T> key");
                return i->second;
        }
        inline size_type count(const key_type& key) const {
                underciter i = std::lower_bound(internal_.begin(), internal_.end(), key, comp_);
                return (i==internal_.end() || comp_(key,*i) ? 0u : 1u);
        }
        template<class rhs_type> 
        inline std::pair<iterator, bool> emplace(rhs_type&& rhs) {
                underiter i = std::lower_bound(internal_.begin(), internal_.end(), rhs, comp_);
                if (i==internal_.end() || comp_(rhs,*i))
                        return std::pair<iterator,bool>(iterator(internal_.emplace(i, std::move(rhs))), true);
                else {
                        *i = std::move(rhs);
                        return std::pair<iterator,bool>(iterator(i), false);
                }
        }
        template<class rhs_type> 
        std::pair<iterator, bool> emplace_hint(const_iterator where, rhs_type&& rhs) {
                //TODO fix insert back
                if (where==internal_.end()) { return std::pair<iterator,bool>(iterator(internal_.emplace(where, std::move(rhs))), true);}
                if (!comp_(rhs,*where)) { return emplace(std::move(rhs));}
                if (where == internal_.begin()) {return std::pair<iterator,bool>(iterator(internal_.emplace(where, std::move(rhs))), true);}
                const_iterator n=where;
                --n;
                if(comp_(rhs,n))  { return emplace(std::move(rhs));}
                return std::pair<iterator,bool>(iterator(internal_.emplace(where, std::move(rhs))), true);
        }
        inline iterator erase(iterator where) {return iterator(internal_.erase(where));}
    inline iterator erase(iterator first, iterator last) {return iterator(internal_.erase(first, last));}
    inline size_type erase(const key_type& key) {
                underiter i = std::lower_bound(internal_.begin(), internal_.end(), key, comp_);
                if (i==internal_.end() || comp_(key,*i))
                        return 0;
                internal_.erase(i);
                return 1;
        }
        template<class predicate>
    inline iterator remove_if(predicate pred) {iterator(internal_.erase(std::remove_if(internal_.begin(),internal_.end(),pred), internal_.end()));}
        inline iterator find(const key_type& key) {
                underiter i = std::lower_bound(internal_.begin(), internal_.end(), key, comp_);
                return iterator((i==internal_.end() || comp_(key,*i)) ? internal_.end() : i);
        }
    inline const_iterator find(const key_type& key) const {
                underciter i = std::lower_bound(internal_.begin(), internal_.end(), key, comp_);
                return const_iterator((i==internal_.end() || comp_(key,*i)) ? internal_.end() : i);
        }
        inline std::pair<iterator, bool> insert(const value_type& rhs) {
                underiter i = std::lower_bound(internal_.begin(), internal_.end(), rhs, comp_);
                if (i==internal_.end() || comp_(rhs,*i)) 
                        return std::pair<iterator, bool>(iterator(internal_.emplace(i, std::move(rhs))), true);
                else {
                        *i = std::move(rhs);
                        return std::pair<iterator, bool>(iterator(i), false);
                }
        }
    iterator insert(const_iterator where, const value_type& rhs) {
                //TODO fix insert back
                if (where==internal_.end()) { return iterator(internal_.insert(where, rhs));}
                if (!comp_(rhs,*where)) { return insert(rhs).first;}
                if (where == internal_.begin()) {return iterator(internal_.insert(where, rhs));}
                underciter n=where;
                --n;
                if(comp_(rhs,*n))  { return insert(rhs).first;}
                return iterator(internal_.insert(where, rhs));
        }
    template<class input_iterator>
        void insert(input_iterator first, input_iterator last) {
                int s = std::distance(first, last);
                while(first!=last) 
                        internal_.insert(internal_.end(),*(first++));
                iterator mid(internal_.end());
                std::advance(mid, -s);
                std::inplace_merge(internal_.begin(), mid, internal_.end());
        }
    template<class rhs_type>
    inline std::pair<iterator, bool> insert(rhs_type&& rhs) {return emplace(std::move(rhs));}
    template<class rhs_type>
    inline iterator insert(const_iterator where, rhs_type&& rhs) {return emplace(where, std::move(rhs));}
        inline mapped_type& operator[](const key_type& key) {return insert(value_type(key, mapped_type())).first->second;}
        inline mapped_type& operator[](const key_type&& key) {return emplace(value_type(std::move(key), mapped_type())).first->second;}
        inline const mapped_type& operator[](const key_type& key) const {return at(key);}
 
        inline void clear() {internal_.clear();}
        inline bool empty() const {return internal_.empty();}
        inline size_type size( ) const {return internal_.size();}
        inline void swap(associative& rhs) {internal_.swap(rhs.internal_); std::swap(comp_,rhs.comp_);}
        inline friend void swap(associative& left, associative& right) {left.swap(right);}
 
        inline allocator_type get_allocator() const {return internal_.get_allocator();}
        inline key_compare key_comp() const{return comp_.key_comp();}
        inline value_compare value_comp() const{return comp_;}
        inline size_type max_size() const{return internal_.max_size();}
 
        inline friend bool operator==(const associative& left, const associative& right) {return std::equal(left.internal_.begin(), left.internal_.end(), right.internal_.begin(), left.comp_);}
        inline friend bool operator!=(const associative& left, const associative& right) {return !std::equal(left.internal_.begin(), left.internal_.end(), right.internal_.begin(), left.comp_);}
        inline friend bool operator< (const associative& left, const associative& right) {return std::lexicographical_compare(left.internal_.begin(), left.internal_.end(), right.internal_.begin(), right.internal_.end(), left.comp_);}
        inline friend bool operator<=(const associative& left, const associative& right) {return std::lexicographical_compare(right.internal_.begin(), right.internal_.end(), left.internal_.begin(), left.internal_.end(), left.comp_);}
        inline friend bool operator> (const associative& left, const associative& right) {return !std::lexicographical_compare(right.internal_.begin(), right.internal_.end(), left.internal_.begin(), left.internal_.end(), left.comp_);}
        inline friend bool operator>=(const associative& left, const associative& right) {return !std::lexicographical_compare(left.internal_.begin(), left.internal_.end(), right.internal_.begin(), right.internal_.end(), left.comp_);}
        
protected:
        undertype_ internal_;
        value_compare comp_;
};
#pragma warning(pop)
namespace std {
template<class key_, class mapped_, class traits_, class undertype_> 
        inline void swap(associative <key_, mapped_, traits_, undertype_>& left, associative <key_, mapped_, traits_, undertype_>& right)
        {left.swap(right);}
};
 
#endif //ASSOCIATIVE_H
 
 
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <string>
#include <vector>
 
 
#ifdef _DEBUG
#define WARMUP_TIME_MILLISECONDS 1
#define TEST_TIME_MILLISECONDS 9
#else
#define WARMUP_TIME_MILLISECONDS 100
#define TEST_TIME_MILLISECONDS 900
#endif
 
template<unsigned int size>
struct payload {
static unsigned int copycount;
        int data[size/4];
        payload() {data[0]=rand()*RAND_MAX+rand();}
#ifdef _DEBUG
        payload(const payload& r) {
                memcpy(data, r.data, sizeof(data)); 
                ++copycount;
        }
        payload& operator=(const payload& r) {
                memcpy(data, r.data, sizeof(data)); 
                ++copycount;
                return *this;
        }
#endif
        bool operator==(const payload& rhs) const {return data[0]==rhs.data[0];}
        bool operator<(const payload& rhs) const {return data[0]<rhs.data[0];}
};
 
template<unsigned int size>
unsigned int payload<size>::copycount;
 
template<class payload, class container>
void test_internal(const std::vector<std::pair<payload, payload>>& data, const char* classname, const char* payloadname) {
        clock_t beg,end,elapsed,freq;
        unsigned int count=0;
        bool timed=false;
        freq = CLOCKS_PER_SEC;
 
        std::vector<std::pair<payload, payload>> shuffled(data.begin(), data.end());
        std::random_shuffle(shuffled.begin(), shuffled.end());
        std::vector<std::pair<payload, payload>> sorted(data.begin(), data.end());
        std::sort(sorted.begin(), sorted.end());
 
        std::cout << payloadname << ' ' << std::setw(4) << data.size() << ' ' << classname << ' ';
        
        timed = false;
        elapsed = 0;
        count = 0;
    do {
                beg = clock();
            container a(data.begin(), data.end());
            end = clock();
                //assert(data.size()==a.size()); //meh, duplicates
                elapsed += end-beg;
            if (elapsed>WARMUP_TIME_MILLISECONDS && !timed) {
                        elapsed =0;
                        count=0;
            timed = true;
            }
                ++count;
        } while(elapsed<TEST_TIME_MILLISECONDS);
        std::cout << std::setw(9) << count << ' ';
        
        timed = false;
        elapsed = 0;
        count = 0;
        {
            container a(data.begin(), data.end());
                do {
                        beg = clock();
                        auto i=a.find(shuffled[count%data.size()].first);
                        end = clock();
                        assert(i != a.end());
                        assert(i->second == shuffled[count%data.size()].second);
                        elapsed += end-beg;
                        if (elapsed>WARMUP_TIME_MILLISECONDS && !timed) {
                                elapsed =0;
                                count=0;
                                timed = true;
                        }
                        ++count;
                } while(elapsed<TEST_TIME_MILLISECONDS);
        }
        std::cout << std::setw(9) << count << ' ';
        
        timed = false;
        elapsed =0;
        count = 0;
        {
                do {
                        container a(data.begin(), data.end());
                        beg = clock();
                        for(unsigned int i=0; i<shuffled.size(); ++i)
                                a.erase(shuffled[i].first);
                        end = clock();
                        assert(a.size()==0);
                        elapsed += end-beg;
                        if (elapsed>WARMUP_TIME_MILLISECONDS && !timed) {
                                elapsed =0;
                                count=0;
                                timed = true;
                        }
                        ++count;
                } while(elapsed<TEST_TIME_MILLISECONDS);
        }
        std::cout << std::setw(9) << count << '\n';
}
 
template<class payload>
void test(const std::vector<std::pair<payload, payload>> &data, const char* payload_name) {
        std::vector<std::pair<payload, payload>> use(data.begin(), data.begin()+8);
        for( ; ; ) {
                test_internal<payload, std::map   <payload,payload>>(use, "std::map", payload_name);
                test_internal<payload, associative<payload,payload,std::less<payload>,std::vector<std::pair<payload,payload>>>>(use, "astv/vec", payload_name);
                if (use.size()<1024)
                        use.insert(use.end(), data.begin()+use.size()*1ull, data.begin()+use.size()*2ull);
                else if (use.size() != data.size())
                        use.insert(use.end(), data.begin()+use.size(), data.end());
                else break;
        }
}
 
//template associative<payload<  4>,payload<  4>,std::less<payload<  4>>,std::list<std::pair<payload<  4>,payload<  4>>>>;
//template associative<payload<  4>,payload<  4>,std::less<payload<  4>>,std::vector<std::pair<payload<  4>,payload<  4>>>>;
//template associative<payload<  4>,payload<  4>,std::less<payload<  4>>,std::deque<std::pair<payload<  4>,payload<  4>>>>;
 
int main() {
        std::vector<std::pair<std::string,std::string>> dynamic_data;
        dynamic_data.reserve(2000);
        {
                std::ifstream i("F:/Code/Contests/About53/2000words.txt");
                std::string line;
                for(;dynamic_data.size()<2000 && i>>line;)
                        dynamic_data.push_back(std::make_pair(line, line));
                std::random_shuffle(dynamic_data.begin(), dynamic_data.end());
        }
        std::cout << "bigger counts are best       inserts   lookups    erases\n";
#ifndef _DEBUG
        //test(dynamic_data,                                            "std::string ");
#endif
        test(std::vector<std::pair<payload<  4>,payload<  4>>>(2000), "payload<  4>");
#ifndef _DEBUG
        test(std::vector<std::pair<payload<  8>,payload<  8>>>(2000), "payload<  8>");
        test(std::vector<std::pair<payload< 16>,payload< 16>>>(2000), "payload< 16>");
        test(std::vector<std::pair<payload< 32>,payload< 32>>>(2000), "payload< 32>");
        test(std::vector<std::pair<payload< 64>,payload< 64>>>(2000), "payload< 64>");
        test(std::vector<std::pair<payload<128>,payload<128>>>(2000), "payload<128>");
#endif
 
        return 0;
}
 
  • upload with new input
  • result: Success     time: 11.23s    memory: 3588 kB     returned value: 0

    bigger counts are best       inserts   lookups    erases
    payload<  4>    8 std::map      8494     17249     47028
    payload<  4>    8 astv/vec     42582     19462     14806
    payload<  4>   16 std::map     15568     10325      9060
    payload<  4>   16 astv/vec     24749     21012     24487
    payload<  4>   32 std::map      9917     38030     16270
    payload<  4>   32 astv/vec     13417     22852     17366
    payload<  4>   64 std::map      5754     18885      2808
    payload<  4>   64 astv/vec     15152     19403      2064
    payload<  4>  128 std::map      3695     20100      2146
    payload<  4>  128 astv/vec      2395     35118       674
    payload<  4>  256 std::map      2221     18474      1959
    payload<  4>  256 astv/vec      4709      1495       193
    payload<  4>  512 std::map      1312     17628       484
    payload<  4>  512 astv/vec      4137     16362        54
    payload<  4> 1024 std::map       561     14299       251
    payload<  4> 1024 astv/vec      2288     34326        14
    payload<  4> 2000 std::map       282     15347       381
    payload<  4> 2000 astv/vec      1182     11001         5
    payload<  8>    8 std::map      4374     18729      3929
    payload<  8>    8 astv/vec     30304     33950     42982
    payload<  8>   16 std::map     10339     99773     12961
    payload<  8>   16 astv/vec     17259     55153      8403
    payload<  8>   32 std::map      6216     33145      5230
    payload<  8>   32 astv/vec     23706      1005      5415
    payload<  8>   64 std::map      3760     31764     21009
    payload<  8>   64 astv/vec      6305     18032      1250
    payload<  8>  128 std::map      3863     55696      2514
    payload<  8>  128 astv/vec      4678     36670       452
    payload<  8>  256 std::map      1948     31258       542
    payload<  8>  256 astv/vec      2765     14004       118
    payload<  8>  512 std::map      1005      5053      1132
    payload<  8>  512 astv/vec      2942     59692        32
    payload<  8> 1024 std::map       524     16027       872
    payload<  8> 1024 astv/vec      1609     14941         9
    payload<  8> 2000 std::map       265     56575       159
    payload<  8> 2000 astv/vec       977     28793         3
    payload< 16>    8 std::map     27065     17193      7565
    payload< 16>    8 astv/vec     37219     49197     15760
    payload< 16>   16 std::map     16394     15111     13320
    payload< 16>   16 astv/vec      2249     71921      9059
    payload< 16>   32 std::map     11392     77381     11646
    payload< 16>   32 astv/vec     21609     23815      3349
    payload< 16>   64 std::map      5715     22497      4762
    payload< 16>   64 astv/vec     12629     36212      2144
    payload< 16>  128 std::map      3080     50989      6386
    payload< 16>  128 astv/vec      3353     14692       285
    payload< 16>  256 std::map      1753     20602      1154
    payload< 16>  256 astv/vec      3738     16916        78
    payload< 16>  512 std::map       942      4329      1114
    payload< 16>  512 astv/vec      2274     18988        22
    payload< 16> 1024 std::map       505     16270       557
    payload< 16> 1024 astv/vec       851     33415         6
    payload< 16> 2000 std::map       254      7113       153
    payload< 16> 2000 astv/vec       631     72038         2
    payload< 32>    8 std::map      3971      4715     34892
    payload< 32>    8 astv/vec     13915     54379      7940
    payload< 32>   16 std::map     12542     15863     18958
    payload< 32>   16 astv/vec     19548     16818     17402
    payload< 32>   32 std::map      7549     23324      5961
    payload< 32>   32 astv/vec     15453     13121      3819
    payload< 32>   64 std::map      5609     24209     12724
    payload< 32>   64 astv/vec     23553     19046       595
    payload< 32>  128 std::map      2859     53808     11252
    payload< 32>  128 astv/vec      3451     91899       159
    payload< 32>  256 std::map      1661     16499      1970
    payload< 32>  256 astv/vec      1914     13582        40
    payload< 32>  512 std::map       764     21648       483
    payload< 32>  512 astv/vec      1016     20307        14
    payload< 32> 1024 std::map       427     15562       269
    payload< 32> 1024 astv/vec       458     14862         3
    payload< 32> 2000 std::map       200     19842       498
    payload< 32> 2000 astv/vec       330     16860         2
    payload< 64>    8 std::map     16715     89995     13932
    payload< 64>    8 astv/vec     17797     17877     20986
    payload< 64>   16 std::map     22304     38568     24309
    payload< 64>   16 astv/vec      2462     42727      8591
    payload< 64>   32 std::map      5090     16806      3448
    payload< 64>   32 astv/vec      6037     25141      1028
    payload< 64>   64 std::map      4494     26550     14032
    payload< 64>   64 astv/vec      3315     18400       592
    payload< 64>  128 std::map      2035     17014      4756
    payload< 64>  128 astv/vec      2158     55235        85
    payload< 64>  256 std::map      1186     57490       806
    payload< 64>  256 astv/vec      2331     17922        21
    payload< 64>  512 std::map       566     14786      1596
    payload< 64>  512 astv/vec       430     21539         6
    payload< 64> 1024 std::map       300     74636      1183
    payload< 64> 1024 astv/vec       212     87165         2
    payload< 64> 2000 std::map       157     15873       102
    payload< 64> 2000 astv/vec       138     14635         2
    payload<128>    8 std::map     21277     38666     29917
    payload<128>    8 astv/vec     13444     39191      3669
    payload<128>   16 std::map     18789     10309      5385
    payload<128>   16 astv/vec      7639     55992      2875
    payload<128>   32 std::map      3955     31880      6741
    payload<128>   32 astv/vec      2232     19284       380
    payload<128>   64 std::map      1967     56004      3801
    payload<128>   64 astv/vec       430     18027       108
    payload<128>  128 std::map      1350     16793      3908
    payload<128>  128 astv/vec      1066     19316        27
    payload<128>  256 std::map       499     91383       455
    payload<128>  256 astv/vec       503     13186         8
    payload<128>  512 std::map       287     47965       476
    payload<128>  512 astv/vec       257     58059         2
    payload<128> 1024 std::map       153     21026       250
    payload<128> 1024 astv/vec       126     25431         2
    payload<128> 2000 std::map        79     14709       192
    payload<128> 2000 astv/vec        63      8600         2