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 | // kjellkod.wordpress.com // Silly example of // Vector vs LinkedList. Random element and linear traversal to // get to the right position. Insertion gives sorted order. // // OBSERVE: please turn on OPTIMIZATION when running this code on your own computer, i.e. something like // g++ -std=c++11 -O3 #include <list> #include <vector> #include <iostream> #include <iomanip> #include <functional> #include <random> #include <iostream> #include <chrono> #include <string> #include <numeric> #include <algorithm> #include <cassert> namespace g2 { typedef std::chrono::high_resolution_clock clock; typedef std::chrono::microseconds microseconds; typedef std::chrono::milliseconds milliseconds; clock::time_point now(){return clock::now();} microseconds intervalUs(const clock::time_point& t1, const clock::time_point& t0) {return std::chrono::duration_cast<microseconds>(t1 - t0);} milliseconds intervalMs(const clock::time_point& t1,const clock::time_point& t0) {return std::chrono::duration_cast<milliseconds>(t1 - t0);} class StopWatch { clock::time_point start_; public: StopWatch() : start_(clock::now()){} clock::time_point restart() { start_ = clock::now(); return start_;} microseconds elapsedUs() { return intervalUs(now(), start_);} milliseconds elapsedMs() {return intervalMs(now(), start_);} }; } // g2 typedef unsigned int Number; typedef std::list<Number> NumbersInList; typedef std::vector<Number> NumbersInVector; typedef long long int TimeValue; /* // Lambda expression for generating a random number using the 'mersenne twister distribution' // http://en.wikipedia.org/wiki/Mersenne_twister auto random_int = [&](const Number& low, const Number& high) -> Number { std::uniform_int_distribution<int> distribution(low, high); std::mt19937 engine((unsigned int)time(0)); // Mersenne twister MT19937 auto generator = std::bind(distribution, engine); return generator(); }; */ // Random integer function from http://www2.research.att.com/~bs/C++0xFAQ.html#std-random int random_int(int low, int high) { using namespace std; static default_random_engine engine {}; typedef uniform_int_distribution<int> Distribution; static Distribution distribution {}; return distribution(engine, Distribution::param_type{low, high}); } // test printout just to see the distribution void print_distribution(std::vector<Number>& values) { for (int i = 0; i<values.size(); ++i) { std::cout << i << '\t'; for (int j=0; j<values[i]; ++j) std::cout << '*'; std::cout << '\n'; } } // Use a template approach to use functor, function pointer or lambda to insert an // element in the input container and return the "time result". // Search is LINEAR. Elements are insert in SORTED order template<typename Container> void linearInsertion(const NumbersInVector& numbers, Container& container) { std::for_each(numbers.begin(), numbers.end(), [&](const Number& n) { auto itr = container.begin(); for (; itr!= container.end(); ++itr) { if ((*itr) >= n) { break; } } container.insert(itr, n); }); } // Measure time in milliseconds for linear insert in a std container template<typename Container> TimeValue linearInsertPerformance(const NumbersInVector& randoms, Container& container) { g2::StopWatch watch; linearInsertion(std::cref(randoms), container); auto time = watch.elapsedUs().count(); return time; } // Delete of an element from a std container. The Delete of an item is from a random position. template<typename Container> void linearErase(Container& container) { // Possibly O(n) to get initially but we use it for the random number generation // and it is only done ONCE auto size = container.size(); while (false == container.empty()) { // force silly linear search to the right position to do a delete Number random_position = random_int(0, size -1); auto itr = container.begin(); // using hand-wrought 'find' to force linear search to the position for (unsigned int idx = 0; idx != random_position; ++idx) { ++itr; // silly linear } container.erase(itr); --size; } } // Measure time in milliseconds for linear remove (i.e. "erase") in a std container template<typename Container> TimeValue linearRemovePerformance(Container& container) { g2::StopWatch watch; linearErase(container); auto time = watch.elapsedUs().count(); return time; } void listVsVectorLinearPerformance(size_t nbr_of_randoms) { // Generate n random values and push to storage NumbersInVector values(nbr_of_randoms); std::for_each(values.begin(), values.end(), [&](Number& n) { n = random_int(0, nbr_of_randoms -1);}); //print_distribution(values); TimeValue list_time; TimeValue list_delete_time; TimeValue vector_time; TimeValue vector_delete_time; std::cout << nbr_of_randoms << ",\t" << std::flush; { // force local scope - to clear up the containers at exit NumbersInList list; list_time = linearInsertPerformance(values, list); list_delete_time = linearRemovePerformance(list); } { NumbersInVector vector; vector_time = linearInsertPerformance(values, vector); std::cout << " " << ", "; vector_delete_time = linearRemovePerformance(vector); } std::cout << list_time << ", " << vector_time << ","; std::cout << "\t\t" << list_delete_time << ", " << vector_delete_time << std::endl << std::flush; } // Used for debugging and verification, // normally disabled template<typename Container> void printValues(const std::string& msg, const Container& values) { std::cout << msg << std::endl; std::for_each(values.begin(), values.end(), [&](const Number& n) { std::cout << " " << n << " "; }); std::cout << "\n" << std::endl; } // disabled normally,. only used to verify during dev,time not test,time template<typename ProspectLinear> void verifyLinearSort(const NumbersInVector& valid_container, const ProspectLinear& container) { auto toCheckItr = container.begin(); std::for_each(valid_container.begin(), valid_container.end(), [&](const Number& n) { assert(toCheckItr != container.end()); Number n2 = (*toCheckItr); if(n != n2) { printValues("\nTrue Linear should be: ", valid_container); printValues("\nError in comparison printing numbers: ", container); std::cout << "check error: " << n << "vs value: " << n2 << std::endl; assert(n == n2 && "not matching numbers"); } ++toCheckItr; }); } int main(int argc, char** argv) { // Generate N random integers and insert them in its proper position in the numerical order using // LINEAR search std::cout << "Comparison of insert and erase (delete) of item from a linked list and vector (array)" << std::endl; std::cout << "Insert is done on random item, with linear search to get to the insert position" << std::endl; std::cout << "Erase is done on a random position within the available elements. Linear search to get to the position" << std::endl; std::cout << "\n\n Linked-list shows close to exponential time usage in contrast to the vectors almost linear time usage"<< std::endl; std::cout << "The HUGE difference is due to that a vector is sequential in memory and thereby is maximazing cache-line usage" << std::endl; std::cout << "The linked-list uses RAM much more and cache-line misses are maximized. " << std::endl; std::cout << "\n\n CONCLUSION: When comparing linked list and vector/array then the linear search COMPLETELY" << std::endl; std::cout << "DOMINATES the time consumption. Cache-line friendly data structures show much promise in speed" << std::endl; std::cout << "The fact that a vector uses many memory shuffling when increasing, inserting deleting elements is of " << std::endl; std::cout << "LIMITED importance compared to the RAM access slow-down for a linked-list" << std::endl; std::cout << "\nFor test results on Windows and Linux please go to: " << std::endl; std::cout << "https://docs.google.com/spreadsheet/pub?key=0AkliMT3ZybjAdGJMU1g5Q0QxWEluWGRzRnZKZjNMMGc&output=html" << std::endl; std::cout << "\n\n********** Times in microseconds**********" << std::endl; std::cout << "Elements ADD (List, Vector)\tERASE(List, Vector)" << std::endl; //[elements, linear add time [ms] [list, vector], linear erase time[ms] [list, vector]" << std::endl; g2::StopWatch watch; listVsVectorLinearPerformance(100); listVsVectorLinearPerformance(200); listVsVectorLinearPerformance(500); listVsVectorLinearPerformance(1000); listVsVectorLinearPerformance(4000); listVsVectorLinearPerformance(10000); listVsVectorLinearPerformance(20000); listVsVectorLinearPerformance(40000); auto total_time_ms = watch.elapsedMs().count(); std::cout << "Exiting test,. the whole measuring took " << total_time_ms << " milliseconds"; std::cout << " (" << total_time_ms/1000 << "seconds or " << total_time_ms/(1000*60) << " minutes)" << std::endl; return 0; } |
Ly8ga2plbGxrb2Qud29yZHByZXNzLmNvbQovLyBTaWxseSBleGFtcGxlIG9mIAovLyBWZWN0b3IgdnMgTGlua2VkTGlzdC4gUmFuZG9tIGVsZW1lbnQgYW5kIGxpbmVhciB0cmF2ZXJzYWwgdG8gCi8vIGdldCB0byB0aGUgcmlnaHQgcG9zaXRpb24uIEluc2VydGlvbiBnaXZlcyBzb3J0ZWQgb3JkZXIuCi8vCi8vIE9CU0VSVkU6IHBsZWFzZSB0dXJuIG9uIE9QVElNSVpBVElPTiB3aGVuIHJ1bm5pbmcgdGhpcyBjb2RlIG9uIHlvdXIgb3duIGNvbXB1dGVyLCBpLmUuIHNvbWV0aGluZyBsaWtlCi8vICAgICAgICAgZysrIC1zdGQ9YysrMTEgLU8zCgoKI2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8cmFuZG9tPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDxudW1lcmljPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8Y2Fzc2VydD4KCm5hbWVzcGFjZSBnMgp7ICAgICAgIAogIHR5cGVkZWYgc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jayBjbG9jazsKICB0eXBlZGVmIHN0ZDo6Y2hyb25vOjptaWNyb3NlY29uZHMgbWljcm9zZWNvbmRzOwogIHR5cGVkZWYgc3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kcyBtaWxsaXNlY29uZHM7CgogIGNsb2NrOjp0aW1lX3BvaW50IG5vdygpe3JldHVybiBjbG9jazo6bm93KCk7fQoKICBtaWNyb3NlY29uZHMgaW50ZXJ2YWxVcyhjb25zdCBjbG9jazo6dGltZV9wb2ludCYgdDEsIGNvbnN0IGNsb2NrOjp0aW1lX3BvaW50JiB0MCkKICB7cmV0dXJuIHN0ZDo6Y2hyb25vOjpkdXJhdGlvbl9jYXN0PG1pY3Jvc2Vjb25kcz4odDEgLSB0MCk7fQoKICBtaWxsaXNlY29uZHMgaW50ZXJ2YWxNcyhjb25zdCBjbG9jazo6dGltZV9wb2ludCYgdDEsY29uc3QgY2xvY2s6OnRpbWVfcG9pbnQmIHQwKQogIHtyZXR1cm4gc3RkOjpjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8bWlsbGlzZWNvbmRzPih0MSAtIHQwKTt9CgoKICBjbGFzcyBTdG9wV2F0Y2gKICB7CiAgICBjbG9jazo6dGltZV9wb2ludCBzdGFydF87CiAgcHVibGljOgogICAgU3RvcFdhdGNoKCkgOiBzdGFydF8oY2xvY2s6Om5vdygpKXt9CiAgICBjbG9jazo6dGltZV9wb2ludCByZXN0YXJ0KCkgICAgICAgICB7IHN0YXJ0XyA9IGNsb2NrOjpub3coKTsgcmV0dXJuIHN0YXJ0Xzt9CiAgICBtaWNyb3NlY29uZHMgZWxhcHNlZFVzKCkgICAgICAgICAgICB7IHJldHVybiBpbnRlcnZhbFVzKG5vdygpLCBzdGFydF8pO30KICAgIG1pbGxpc2Vjb25kcyBlbGFwc2VkTXMoKSAgICAgICAgICAgIHtyZXR1cm4gaW50ZXJ2YWxNcyhub3coKSwgc3RhcnRfKTt9CiAgfTsKfSAvLyBnMgoKCgoKCnR5cGVkZWYgdW5zaWduZWQgaW50ICBOdW1iZXI7CnR5cGVkZWYgc3RkOjpsaXN0PE51bWJlcj4gICAgICAgICAgIE51bWJlcnNJbkxpc3Q7CnR5cGVkZWYgc3RkOjp2ZWN0b3I8TnVtYmVyPiAgICAgICAgIE51bWJlcnNJblZlY3RvcjsKdHlwZWRlZiBsb25nIGxvbmcgaW50ICAgICAgICAgICAgICAgVGltZVZhbHVlOwoKCi8qICAgLy8gTGFtYmRhIGV4cHJlc3Npb24gZm9yIGdlbmVyYXRpbmcgYSByYW5kb20gbnVtYmVyIHVzaW5nIHRoZSAnbWVyc2VubmUgdHdpc3RlciBkaXN0cmlidXRpb24nCiAgICAgLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NZXJzZW5uZV90d2lzdGVyCmF1dG8gcmFuZG9tX2ludCA9IFsmXShjb25zdCBOdW1iZXImIGxvdywgY29uc3QgTnVtYmVyJiBoaWdoKSAtPiBOdW1iZXIgewogICAgc3RkOjp1bmlmb3JtX2ludF9kaXN0cmlidXRpb248aW50PiBkaXN0cmlidXRpb24obG93LCBoaWdoKTsKICAgIHN0ZDo6bXQxOTkzNyBlbmdpbmUoKHVuc2lnbmVkIGludCl0aW1lKDApKTsgLy8gTWVyc2VubmUgdHdpc3RlciBNVDE5OTM3CiAgICBhdXRvIGdlbmVyYXRvciA9IHN0ZDo6YmluZChkaXN0cmlidXRpb24sIGVuZ2luZSk7CiAgICByZXR1cm4gZ2VuZXJhdG9yKCk7Cn07ICAgKi8KCi8vIFJhbmRvbSBpbnRlZ2VyIGZ1bmN0aW9uIGZyb20gaHR0cDovL3d3dzIucmVzZWFyY2guYXR0LmNvbS9+YnMvQysrMHhGQVEuaHRtbCNzdGQtcmFuZG9tCmludCByYW5kb21faW50KGludCBsb3csIGludCBoaWdoKQp7CiAgdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiAgc3RhdGljIGRlZmF1bHRfcmFuZG9tX2VuZ2luZSBlbmdpbmUge307CiAgdHlwZWRlZiB1bmlmb3JtX2ludF9kaXN0cmlidXRpb248aW50PiBEaXN0cmlidXRpb247CiAgc3RhdGljIERpc3RyaWJ1dGlvbiBkaXN0cmlidXRpb24ge307CgogIHJldHVybiBkaXN0cmlidXRpb24oZW5naW5lLCBEaXN0cmlidXRpb246OnBhcmFtX3R5cGV7bG93LCBoaWdofSk7Cn0KCi8vIHRlc3QgcHJpbnRvdXQganVzdCB0byBzZWUgdGhlIGRpc3RyaWJ1dGlvbgp2b2lkIHByaW50X2Rpc3RyaWJ1dGlvbihzdGQ6OnZlY3RvcjxOdW1iZXI+JiB2YWx1ZXMpCnsgIAogIGZvciAoaW50IGkgPSAwOyBpPHZhbHVlcy5zaXplKCk7ICsraSkgCiAgewogICAgc3RkOjpjb3V0IDw8IGkgPDwgJ1x0JzsKICAgIGZvciAoaW50IGo9MDsgajx2YWx1ZXNbaV07ICsraikgc3RkOjpjb3V0IDw8ICcqJzsKICAgIHN0ZDo6Y291dCA8PCAnXG4nOwogIH0KfQoKCgoKLy8gVXNlIGEgdGVtcGxhdGUgYXBwcm9hY2ggdG8gdXNlIGZ1bmN0b3IsIGZ1bmN0aW9uIHBvaW50ZXIgb3IgbGFtYmRhIHRvIGluc2VydCBhbgovLyBlbGVtZW50IGluIHRoZSBpbnB1dCBjb250YWluZXIgYW5kIHJldHVybiB0aGUgInRpbWUgcmVzdWx0Ii4KLy8gU2VhcmNoIGlzIExJTkVBUi4gRWxlbWVudHMgYXJlIGluc2VydCBpbiBTT1JURUQgb3JkZXIKdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgp2b2lkIGxpbmVhckluc2VydGlvbihjb25zdCBOdW1iZXJzSW5WZWN0b3ImIG51bWJlcnMsIENvbnRhaW5lciYgY29udGFpbmVyKQp7CiAgICBzdGQ6OmZvcl9lYWNoKG51bWJlcnMuYmVnaW4oKSwgbnVtYmVycy5lbmQoKSwKICAgICAgICAgICAgICAgICAgWyZdKGNvbnN0IE51bWJlciYgbikKICAgIHsKICAgICAgICBhdXRvIGl0ciA9IGNvbnRhaW5lci5iZWdpbigpOwogICAgICAgIGZvciAoOyBpdHIhPSBjb250YWluZXIuZW5kKCk7ICsraXRyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgqaXRyKSA+PSBuKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb250YWluZXIuaW5zZXJ0KGl0ciwgbik7CiAgICB9KTsKfQoKLy8gTWVhc3VyZSB0aW1lIGluIG1pbGxpc2Vjb25kcyBmb3IgbGluZWFyIGluc2VydCBpbiBhIHN0ZCBjb250YWluZXIKdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgpUaW1lVmFsdWUgbGluZWFySW5zZXJ0UGVyZm9ybWFuY2UoY29uc3QgTnVtYmVyc0luVmVjdG9yJiByYW5kb21zLCBDb250YWluZXImIGNvbnRhaW5lcikKewogICAgZzI6OlN0b3BXYXRjaCB3YXRjaDsKICAgIGxpbmVhckluc2VydGlvbihzdGQ6OmNyZWYocmFuZG9tcyksIGNvbnRhaW5lcik7CiAgICBhdXRvIHRpbWUgPSB3YXRjaC5lbGFwc2VkVXMoKS5jb3VudCgpOwogICAgcmV0dXJuIHRpbWU7Cn0KCgoKLy8gRGVsZXRlIG9mIGFuIGVsZW1lbnQgZnJvbSBhIHN0ZCBjb250YWluZXIuIFRoZSBEZWxldGUgb2YgYW4gaXRlbSBpcyBmcm9tIGEgcmFuZG9tIHBvc2l0aW9uLgp0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+CnZvaWQgbGluZWFyRXJhc2UoQ29udGFpbmVyJiBjb250YWluZXIpCnsKICAgIC8vIFBvc3NpYmx5IE8obikgdG8gZ2V0IGluaXRpYWxseSBidXQgd2UgdXNlIGl0IGZvciB0aGUgcmFuZG9tIG51bWJlciBnZW5lcmF0aW9uCiAgICAvLyAgICBhbmQgaXQgaXMgb25seSBkb25lIE9OQ0UKICAgIGF1dG8gc2l6ZSA9IGNvbnRhaW5lci5zaXplKCk7CiAgICB3aGlsZSAoZmFsc2UgPT0gY29udGFpbmVyLmVtcHR5KCkpCiAgICB7CiAgICAgICAgLy8gZm9yY2Ugc2lsbHkgbGluZWFyIHNlYXJjaCB0byB0aGUgcmlnaHQgcG9zaXRpb24gdG8gZG8gYSBkZWxldGUKICAgICAgICBOdW1iZXIgcmFuZG9tX3Bvc2l0aW9uID0gcmFuZG9tX2ludCgwLCBzaXplIC0xKTsKICAgICAgICBhdXRvIGl0ciA9IGNvbnRhaW5lci5iZWdpbigpOwoKICAgICAgICAvLyB1c2luZyBoYW5kLXdyb3VnaHQgJ2ZpbmQnIHRvIGZvcmNlIGxpbmVhciBzZWFyY2ggdG8gdGhlIHBvc2l0aW9uCiAgICAgICAgZm9yICh1bnNpZ25lZCBpbnQgaWR4ID0gMDsgaWR4ICE9IHJhbmRvbV9wb3NpdGlvbjsgKytpZHgpCiAgICAgICAgewogICAgICAgICAgICArK2l0cjsgLy8gc2lsbHkgbGluZWFyCiAgICAgICAgfQogICAgICAgIGNvbnRhaW5lci5lcmFzZShpdHIpOwogICAgICAgIC0tc2l6ZTsKICAgIH0KfQoKLy8gTWVhc3VyZSB0aW1lIGluIG1pbGxpc2Vjb25kcyBmb3IgbGluZWFyIHJlbW92ZSAoaS5lLiAiZXJhc2UiKSBpbiBhIHN0ZCBjb250YWluZXIKdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgpUaW1lVmFsdWUgbGluZWFyUmVtb3ZlUGVyZm9ybWFuY2UoQ29udGFpbmVyJiBjb250YWluZXIpCnsKICAgIGcyOjpTdG9wV2F0Y2ggd2F0Y2g7CiAgICBsaW5lYXJFcmFzZShjb250YWluZXIpOwogICAgYXV0byB0aW1lID0gd2F0Y2guZWxhcHNlZFVzKCkuY291bnQoKTsKICAgIHJldHVybiB0aW1lOwp9CgoKdm9pZCBsaXN0VnNWZWN0b3JMaW5lYXJQZXJmb3JtYW5jZShzaXplX3QgbmJyX29mX3JhbmRvbXMpCnsKICAvLyBHZW5lcmF0ZSBuIHJhbmRvbSB2YWx1ZXMgYW5kIHB1c2ggdG8gc3RvcmFnZQogIE51bWJlcnNJblZlY3RvciAgICAgdmFsdWVzKG5icl9vZl9yYW5kb21zKTsKICBzdGQ6OmZvcl9lYWNoKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCksIFsmXShOdW1iZXImIG4pIHsgbiA9IHJhbmRvbV9pbnQoMCwgbmJyX29mX3JhbmRvbXMgLTEpO30pOyAKICAvL3ByaW50X2Rpc3RyaWJ1dGlvbih2YWx1ZXMpOyAKCiAgVGltZVZhbHVlIGxpc3RfdGltZTsKICBUaW1lVmFsdWUgbGlzdF9kZWxldGVfdGltZTsKICBUaW1lVmFsdWUgdmVjdG9yX3RpbWU7ICAgIAogIFRpbWVWYWx1ZSB2ZWN0b3JfZGVsZXRlX3RpbWU7CiAgc3RkOjpjb3V0IDw8IG5icl9vZl9yYW5kb21zIDw8ICIsXHQiIDw8IHN0ZDo6Zmx1c2g7CgoKICB7IC8vIGZvcmNlIGxvY2FsIHNjb3BlIC0gdG8gY2xlYXIgdXAgdGhlIGNvbnRhaW5lcnMgYXQgZXhpdAkKICAgIE51bWJlcnNJbkxpc3QgICAgICBsaXN0OwogICAgbGlzdF90aW1lID0gbGluZWFySW5zZXJ0UGVyZm9ybWFuY2UodmFsdWVzLCBsaXN0KTsKICAgIGxpc3RfZGVsZXRlX3RpbWUgPSBsaW5lYXJSZW1vdmVQZXJmb3JtYW5jZShsaXN0KTsKICB9CiAgewogICAgTnVtYmVyc0luVmVjdG9yICAgIHZlY3RvcjsKICAgIHZlY3Rvcl90aW1lID0gbGluZWFySW5zZXJ0UGVyZm9ybWFuY2UodmFsdWVzLCB2ZWN0b3IpOwogICAgc3RkOjpjb3V0IDw8ICIgIiAgPDwgIiwgIjsKICAgIHZlY3Rvcl9kZWxldGVfdGltZSA9IGxpbmVhclJlbW92ZVBlcmZvcm1hbmNlKHZlY3Rvcik7CiAgfQogIHN0ZDo6Y291dCA8PCAgbGlzdF90aW1lIDw8ICIsICIgPDwgdmVjdG9yX3RpbWUgPDwgIiwiOwogIHN0ZDo6Y291dCA8PCAiXHRcdCIgPDwgbGlzdF9kZWxldGVfdGltZSA8PCAiLCAiIDw8IHZlY3Rvcl9kZWxldGVfdGltZSA8PCBzdGQ6OmVuZGwgPDwgc3RkOjpmbHVzaDsKfQoKCgoKLy8gVXNlZCBmb3IgZGVidWdnaW5nIGFuZCB2ZXJpZmljYXRpb24sIAovLyBub3JtYWxseSBkaXNhYmxlZAp0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+CnZvaWQgcHJpbnRWYWx1ZXMoY29uc3Qgc3RkOjpzdHJpbmcmIG1zZywgY29uc3QgQ29udGFpbmVyJiB2YWx1ZXMpCnsKICBzdGQ6OmNvdXQgPDwgbXNnIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmZvcl9lYWNoKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCksCiAgICBbJl0oY29uc3QgTnVtYmVyJiBuKSB7IHN0ZDo6Y291dCA8PCAiICIgPDwgbiA8PCAiICI7IH0pOyAKCiAgc3RkOjpjb3V0IDw8ICJcbiIgPDwgc3RkOjplbmRsOwp9CgoKCi8vIGRpc2FibGVkIG5vcm1hbGx5LC4gb25seSB1c2VkIHRvIHZlcmlmeSBkdXJpbmcgZGV2LHRpbWUgbm90IHRlc3QsdGltZQp0ZW1wbGF0ZTx0eXBlbmFtZSBQcm9zcGVjdExpbmVhcj4Kdm9pZCB2ZXJpZnlMaW5lYXJTb3J0KGNvbnN0IE51bWJlcnNJblZlY3RvciYgdmFsaWRfY29udGFpbmVyLCBjb25zdCBQcm9zcGVjdExpbmVhciYgY29udGFpbmVyKQp7CiAgYXV0byB0b0NoZWNrSXRyID0gY29udGFpbmVyLmJlZ2luKCk7CiAgc3RkOjpmb3JfZWFjaCh2YWxpZF9jb250YWluZXIuYmVnaW4oKSwgdmFsaWRfY29udGFpbmVyLmVuZCgpLAogICAgWyZdKGNvbnN0IE51bWJlciYgbikKICB7CiAgICBhc3NlcnQodG9DaGVja0l0ciAhPSBjb250YWluZXIuZW5kKCkpOwogICAgTnVtYmVyIG4yID0gKCp0b0NoZWNrSXRyKTsKICAgIGlmKG4gIT0gbjIpCiAgICB7CiAgICAgIHByaW50VmFsdWVzKCJcblRydWUgTGluZWFyIHNob3VsZCBiZTogIiwgdmFsaWRfY29udGFpbmVyKTsKICAgICAgcHJpbnRWYWx1ZXMoIlxuRXJyb3IgaW4gY29tcGFyaXNvbiBwcmludGluZyBudW1iZXJzOiAiLCBjb250YWluZXIpOwogICAgICBzdGQ6OmNvdXQgPDwgImNoZWNrIGVycm9yOiAiIDw8IG4gPDwgInZzIHZhbHVlOiAiIDw8IG4yIDw8IHN0ZDo6ZW5kbDsKICAgICAgYXNzZXJ0KG4gPT0gbjIgJiYgIm5vdCBtYXRjaGluZyBudW1iZXJzIik7CiAgICB9CiAgICArK3RvQ2hlY2tJdHI7CiAgfSk7Cn0KCgoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KQp7IAoKICAvLyBHZW5lcmF0ZSBOIHJhbmRvbSBpbnRlZ2VycyBhbmQgaW5zZXJ0IHRoZW0gaW4gaXRzIHByb3BlciBwb3NpdGlvbiBpbiB0aGUgbnVtZXJpY2FsIG9yZGVyIHVzaW5nCiAgLy8gTElORUFSIHNlYXJjaAogIHN0ZDo6Y291dCA8PCAiQ29tcGFyaXNvbiBvZiBpbnNlcnQgYW5kIGVyYXNlIChkZWxldGUpIG9mIGl0ZW0gZnJvbSBhIGxpbmtlZCBsaXN0IGFuZCB2ZWN0b3IgKGFycmF5KSIgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCAiSW5zZXJ0IGlzIGRvbmUgb24gcmFuZG9tIGl0ZW0sIHdpdGggbGluZWFyIHNlYXJjaCB0byBnZXQgdG8gdGhlIGluc2VydCBwb3NpdGlvbiIgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCAiRXJhc2UgaXMgZG9uZSBvbiBhIHJhbmRvbSBwb3NpdGlvbiB3aXRoaW4gdGhlIGF2YWlsYWJsZSBlbGVtZW50cy4gTGluZWFyIHNlYXJjaCB0byBnZXQgdG8gdGhlIHBvc2l0aW9uIiA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJcblxuIExpbmtlZC1saXN0IHNob3dzIGNsb3NlIHRvIGV4cG9uZW50aWFsIHRpbWUgdXNhZ2UgaW4gY29udHJhc3QgdG8gdGhlIHZlY3RvcnMgYWxtb3N0IGxpbmVhciB0aW1lIHVzYWdlIjw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQgPDwgIlRoZSBIVUdFIGRpZmZlcmVuY2UgaXMgZHVlIHRvIHRoYXQgYSB2ZWN0b3IgaXMgc2VxdWVudGlhbCBpbiBtZW1vcnkgYW5kIHRoZXJlYnkgaXMgbWF4aW1hemluZyBjYWNoZS1saW5lIHVzYWdlIiA8PCBzdGQ6OmVuZGw7CiBzdGQ6OmNvdXQgPDwgIlRoZSBsaW5rZWQtbGlzdCB1c2VzIFJBTSBtdWNoIG1vcmUgYW5kIGNhY2hlLWxpbmUgbWlzc2VzIGFyZSBtYXhpbWl6ZWQuICIgPDwgc3RkOjplbmRsOwogc3RkOjpjb3V0IDw8ICJcblxuIENPTkNMVVNJT046IFdoZW4gY29tcGFyaW5nIGxpbmtlZCBsaXN0IGFuZCB2ZWN0b3IvYXJyYXkgdGhlbiB0aGUgbGluZWFyIHNlYXJjaCBDT01QTEVURUxZIiA8PCBzdGQ6OmVuZGw7IAogc3RkOjpjb3V0IDw8ICJET01JTkFURVMgdGhlIHRpbWUgY29uc3VtcHRpb24uIENhY2hlLWxpbmUgZnJpZW5kbHkgZGF0YSBzdHJ1Y3R1cmVzIHNob3cgbXVjaCBwcm9taXNlIGluIHNwZWVkIiA8PCBzdGQ6OmVuZGw7CiBzdGQ6OmNvdXQgPDwgIlRoZSBmYWN0IHRoYXQgYSB2ZWN0b3IgdXNlcyBtYW55IG1lbW9yeSBzaHVmZmxpbmcgd2hlbiBpbmNyZWFzaW5nLCBpbnNlcnRpbmcgZGVsZXRpbmcgZWxlbWVudHMgaXMgb2YgIiA8PCBzdGQ6OmVuZGw7IApzdGQ6OmNvdXQgPDwgIkxJTUlURUQgaW1wb3J0YW5jZSBjb21wYXJlZCB0byB0aGUgUkFNIGFjY2VzcyBzbG93LWRvd24gZm9yIGEgbGlua2VkLWxpc3QiIDw8IHN0ZDo6ZW5kbDsKCnN0ZDo6Y291dCA8PCAiXG5Gb3IgdGVzdCByZXN1bHRzIG9uIFdpbmRvd3MgYW5kIExpbnV4IHBsZWFzZSBnbyB0bzogIiA8PCBzdGQ6OmVuZGw7CnN0ZDo6Y291dCA8PCAiaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXQvcHViP2tleT0wQWtsaU1UM1p5YmpBZEdKTVUxZzVRMFF4V0VsdVdHUnpSblpLWmpOTU1HYyZvdXRwdXQ9aHRtbCIgPDwgc3RkOjplbmRsOwoKc3RkOjpjb3V0IDw8ICJcblxuKioqKioqKioqKiBUaW1lcyBpbiBtaWNyb3NlY29uZHMqKioqKioqKioqIiA8PCBzdGQ6OmVuZGw7CnN0ZDo6Y291dCA8PCAiRWxlbWVudHMgQUREIChMaXN0LCBWZWN0b3IpXHRFUkFTRShMaXN0LCBWZWN0b3IpIiA8PCBzdGQ6OmVuZGw7Ci8vW2VsZW1lbnRzLCBsaW5lYXIgYWRkIHRpbWUgW21zXSBbbGlzdCwgdmVjdG9yXSwgICAgbGluZWFyIGVyYXNlIHRpbWVbbXNdIFtsaXN0LCB2ZWN0b3JdIiA8PCBzdGQ6OmVuZGw7CgogIGcyOjpTdG9wV2F0Y2ggd2F0Y2g7CiAgbGlzdFZzVmVjdG9yTGluZWFyUGVyZm9ybWFuY2UoMTAwKTsKICBsaXN0VnNWZWN0b3JMaW5lYXJQZXJmb3JtYW5jZSgyMDApOwogIGxpc3RWc1ZlY3RvckxpbmVhclBlcmZvcm1hbmNlKDUwMCk7CiAgbGlzdFZzVmVjdG9yTGluZWFyUGVyZm9ybWFuY2UoMTAwMCk7CiAgbGlzdFZzVmVjdG9yTGluZWFyUGVyZm9ybWFuY2UoNDAwMCk7CiAgbGlzdFZzVmVjdG9yTGluZWFyUGVyZm9ybWFuY2UoMTAwMDApOwogIGxpc3RWc1ZlY3RvckxpbmVhclBlcmZvcm1hbmNlKDIwMDAwKTsKICBsaXN0VnNWZWN0b3JMaW5lYXJQZXJmb3JtYW5jZSg0MDAwMCk7CiAgYXV0byB0b3RhbF90aW1lX21zID0gd2F0Y2guZWxhcHNlZE1zKCkuY291bnQoKTsKCiAgc3RkOjpjb3V0IDw8ICJFeGl0aW5nIHRlc3QsLiB0aGUgd2hvbGUgbWVhc3VyaW5nIHRvb2sgIiA8PCB0b3RhbF90aW1lX21zIDw8ICIgbWlsbGlzZWNvbmRzIjsKICBzdGQ6OmNvdXQgPDwgIiAoIiA8PCB0b3RhbF90aW1lX21zLzEwMDAgPDwgInNlY29uZHMgb3IgIiA8PCB0b3RhbF90aW1lX21zLygxMDAwKjYwKSA8PCAiIG1pbnV0ZXMpIiA8PCBzdGQ6OmVuZGw7IAogICByZXR1cm4gMDsKfQ==
-
upload with new input
-
result: Success time: 9.77s memory: 3124 kB returned value: 0
Comparison of insert and erase (delete) of item from a linked list and vector (array) Insert is done on random item, with linear search to get to the insert position Erase is done on a random position within the available elements. Linear search to get to the position Linked-list shows close to exponential time usage in contrast to the vectors almost linear time usage The HUGE difference is due to that a vector is sequential in memory and thereby is maximazing cache-line usage The linked-list uses RAM much more and cache-line misses are maximized. CONCLUSION: When comparing linked list and vector/array then the linear search COMPLETELY DOMINATES the time consumption. Cache-line friendly data structures show much promise in speed The fact that a vector uses many memory shuffling when increasing, inserting deleting elements is of LIMITED importance compared to the RAM access slow-down for a linked-list For test results on Windows and Linux please go to: https://docs.google.com/spreadsheet/pub?key=0AkliMT3ZybjAdGJMU1g5Q0QxWEluWGRzRnZKZjNMMGc&output=html ********** Times in microseconds********** Elements ADD (List, Vector) ERASE(List, Vector) 100, , 16, 15, 22, 9 200, , 33, 35, 33, 19 500, , 134, 153, 131, 66 1000, , 550, 513, 451, 185 4000, , 6809, 7318, 5900, 2081 10000, , 100421, 44943, 110069, 11790 20000, , 589209, 182490, 606982, 46515 40000, , 3430062, 797146, 3638707, 250067 Exiting test,. the whole measuring took 9837 milliseconds (9seconds or 0 minutes)


