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 | /* Hack of earlier code to compare vectors worst-case towards linked-list best case I.e. 1) insertion of x elements at first position 1b) The same but do for vector at last position */ #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; 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)); } template<typename Container> void firstPositionInsertion(const NumbersInVector& numbers, Container& container) { std::for_each(numbers.begin(), numbers.end(), [&](const Number& n) { auto itr = container.begin(); container.insert(itr, n); }); } // For vector, push always at back position TimeValue lastPositionInsertionPerformance(const NumbersInVector& numbers, NumbersInVector& vector) { g2::StopWatch watch; std::for_each(numbers.begin(), numbers.end(), [&](const Number& n) { vector.push_back(n); }); auto time = watch.elapsedUs().count(); return time; } // Measure time in milliseconds for linear insert in a std container template<typename Container> TimeValue linearInsertPerformance(const NumbersInVector& randoms, Container& container) { g2::StopWatch watch; firstPositionInsertion(std::cref(randoms), container); auto time = watch.elapsedUs().count(); return time; } void addPerformance(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);}); NumbersInVector vector_worst; NumbersInVector vector_best; NumbersInList list; std::cout << nbr_of_randoms << ", " << std::flush; TimeValue list_time = linearInsertPerformance(values, list); TimeValue vector_best_time = lastPositionInsertionPerformance(values, vector_best); TimeValue vector_worst_time = linearInsertPerformance(values, vector_worst); std::cout << list_time << ", " << vector_best_time << ", " << vector_worst_time << " " << std::endl << std::flush; } int main(int argc, char** argv) { std::cout << "Perhaps the most common 'data collecting' operation is putting 'one piece of data" << std::endl; std::cout << " in front of an older piece of data and so forth.\n" << std::endl; std::cout << "For linked-list this is insertion at index 0\n" << std::endl; std::cout << "For std::vector the 'push at front' operation is working against nature of the " << std::endl; std::cout << " data structure and in this common scenario such use is called 'naive'\n" << std::endl; std::cout << "For std::vector it is natural in this scenario to work in the direction of 'growth' " << std::endl; std::cout << "i.e. push_back. It solves the same task but works as intended with the nature of the " << std::endl; std::cout << " data structure.\n\n" << std::endl; std::cout << "elements, list, vector_best, vector_worst(naive)" << std::endl; g2::StopWatch watch; addPerformance(10); addPerformance(100); addPerformance(500); addPerformance(1000); addPerformance(2000); addPerformance(10000); addPerformance(20000); addPerformance(40000); addPerformance(100000); // more than this will timeout on ideone // addPerformance(500000); //addPerformance(1000000); 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; } |
LyogSGFjayBvZiBlYXJsaWVyIGNvZGUgdG8gY29tcGFyZSB2ZWN0b3JzIHdvcnN0LWNhc2UgdG93YXJkcyBsaW5rZWQtbGlzdCBiZXN0IGNhc2UKSS5lLiAxKSBpbnNlcnRpb24gb2YgeCBlbGVtZW50cyBhdCBmaXJzdCBwb3NpdGlvbgogICAgIDFiKSBUaGUgc2FtZSBidXQgZG8gZm9yIHZlY3RvciBhdCBsYXN0IHBvc2l0aW9uCiovCgojaW5jbHVkZSA8bGlzdD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxyYW5kb20+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGNocm9ubz4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPG51bWVyaWM+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxjYXNzZXJ0PgoKbmFtZXNwYWNlIGcyCnsgICAgICAgCiAgdHlwZWRlZiBzdGQ6OmNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrIGNsb2NrOwogIHR5cGVkZWYgc3RkOjpjaHJvbm86Om1pY3Jvc2Vjb25kcyBtaWNyb3NlY29uZHM7CiAgdHlwZWRlZiBzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzIG1pbGxpc2Vjb25kczsKCiAgY2xvY2s6OnRpbWVfcG9pbnQgbm93KCl7cmV0dXJuIGNsb2NrOjpub3coKTt9CgogIG1pY3Jvc2Vjb25kcyBpbnRlcnZhbFVzKGNvbnN0IGNsb2NrOjp0aW1lX3BvaW50JiB0MSwgY29uc3QgY2xvY2s6OnRpbWVfcG9pbnQmIHQwKQogIHtyZXR1cm4gc3RkOjpjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8bWljcm9zZWNvbmRzPih0MSAtIHQwKTt9CgogIG1pbGxpc2Vjb25kcyBpbnRlcnZhbE1zKGNvbnN0IGNsb2NrOjp0aW1lX3BvaW50JiB0MSxjb25zdCBjbG9jazo6dGltZV9wb2ludCYgdDApCiAge3JldHVybiBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxtaWxsaXNlY29uZHM+KHQxIC0gdDApO30KCgogIGNsYXNzIFN0b3BXYXRjaAogIHsKICAgIGNsb2NrOjp0aW1lX3BvaW50IHN0YXJ0XzsKICBwdWJsaWM6CiAgICBTdG9wV2F0Y2goKSA6IHN0YXJ0XyhjbG9jazo6bm93KCkpe30KICAgIGNsb2NrOjp0aW1lX3BvaW50IHJlc3RhcnQoKSAgICAgICAgIHsgc3RhcnRfID0gY2xvY2s6Om5vdygpOyByZXR1cm4gc3RhcnRfO30KICAgIG1pY3Jvc2Vjb25kcyBlbGFwc2VkVXMoKSAgICAgICAgICAgIHsgcmV0dXJuIGludGVydmFsVXMobm93KCksIHN0YXJ0Xyk7fQogICAgbWlsbGlzZWNvbmRzIGVsYXBzZWRNcygpICAgICAgICAgICAge3JldHVybiBpbnRlcnZhbE1zKG5vdygpLCBzdGFydF8pO30KICB9Owp9IC8vIGcyCgoKdHlwZWRlZiB1bnNpZ25lZCBpbnQgIE51bWJlcjsKdHlwZWRlZiBzdGQ6Omxpc3Q8TnVtYmVyPiAgICAgICAgICAgTnVtYmVyc0luTGlzdDsKdHlwZWRlZiBzdGQ6OnZlY3RvcjxOdW1iZXI+ICAgICAgICAgTnVtYmVyc0luVmVjdG9yOwp0eXBlZGVmIGxvbmcgbG9uZyBpbnQgICAgICAgICAgICAgICBUaW1lVmFsdWU7CgoKaW50IHJhbmRvbV9pbnQoaW50IGxvdywgaW50IGhpZ2gpCnsKICB1c2luZyBuYW1lc3BhY2Ugc3RkOwogIHN0YXRpYyBkZWZhdWx0X3JhbmRvbV9lbmdpbmUgZW5naW5lOwogIHR5cGVkZWYgdW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGludD4gRGlzdHJpYnV0aW9uOwogIHN0YXRpYyBEaXN0cmlidXRpb24gZGlzdHJpYnV0aW9uOwogIHJldHVybiBkaXN0cmlidXRpb24oZW5naW5lLCBEaXN0cmlidXRpb246OnBhcmFtX3R5cGUobG93LCBoaWdoKSk7Cn0KdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgp2b2lkIGZpcnN0UG9zaXRpb25JbnNlcnRpb24oY29uc3QgTnVtYmVyc0luVmVjdG9yJiBudW1iZXJzLCBDb250YWluZXImIGNvbnRhaW5lcikKewogICAgc3RkOjpmb3JfZWFjaChudW1iZXJzLmJlZ2luKCksIG51bWJlcnMuZW5kKCksCiAgICAgICAgICAgICAgICAgIFsmXShjb25zdCBOdW1iZXImIG4pCiAgICB7CiAgICAgICAgYXV0byBpdHIgPSBjb250YWluZXIuYmVnaW4oKTsKICAgICAgICBjb250YWluZXIuaW5zZXJ0KGl0ciwgbik7CiAgICB9KTsKfQoKLy8gRm9yIHZlY3RvciwgcHVzaCBhbHdheXMgYXQgYmFjayBwb3NpdGlvbgpUaW1lVmFsdWUgbGFzdFBvc2l0aW9uSW5zZXJ0aW9uUGVyZm9ybWFuY2UoY29uc3QgTnVtYmVyc0luVmVjdG9yJiBudW1iZXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1iZXJzSW5WZWN0b3ImIHZlY3RvcikKewogICAgZzI6OlN0b3BXYXRjaCB3YXRjaDsKICAgIHN0ZDo6Zm9yX2VhY2gobnVtYmVycy5iZWdpbigpLCBudW1iZXJzLmVuZCgpLAogICAgICAgICAgICAgICAgICBbJl0oY29uc3QgTnVtYmVyJiBuKQogICAgewoJICAgIHZlY3Rvci5wdXNoX2JhY2sobik7CiAgICB9KTsKCglhdXRvIHRpbWUgPSB3YXRjaC5lbGFwc2VkVXMoKS5jb3VudCgpOwogICAgcmV0dXJuIHRpbWU7Cn0KCgovLyBNZWFzdXJlIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGZvciBsaW5lYXIgaW5zZXJ0IGluIGEgc3RkIGNvbnRhaW5lcgp0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+ClRpbWVWYWx1ZSBsaW5lYXJJbnNlcnRQZXJmb3JtYW5jZShjb25zdCBOdW1iZXJzSW5WZWN0b3ImIHJhbmRvbXMsIENvbnRhaW5lciYgY29udGFpbmVyKQp7CiAgICBnMjo6U3RvcFdhdGNoIHdhdGNoOwogICAgZmlyc3RQb3NpdGlvbkluc2VydGlvbihzdGQ6OmNyZWYocmFuZG9tcyksIGNvbnRhaW5lcik7CiAgICBhdXRvIHRpbWUgPSB3YXRjaC5lbGFwc2VkVXMoKS5jb3VudCgpOwogICAgcmV0dXJuIHRpbWU7Cn0KCgoKdm9pZCBhZGRQZXJmb3JtYW5jZShzaXplX3QgbmJyX29mX3JhbmRvbXMpCnsKICAvLyBHZW5lcmF0ZSBuIHJhbmRvbSB2YWx1ZXMgYW5kIHB1c2ggdG8gc3RvcmFnZQogIE51bWJlcnNJblZlY3RvciAgICAgdmFsdWVzKG5icl9vZl9yYW5kb21zKTsKICBzdGQ6OmZvcl9lYWNoKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCksIFsmXShOdW1iZXImIG4pIHsgbiA9IHJhbmRvbV9pbnQoMCwgbmJyX29mX3JhbmRvbXMgLTEpO30pOyAKCiAgTnVtYmVyc0luVmVjdG9yIHZlY3Rvcl93b3JzdDsKICBOdW1iZXJzSW5WZWN0b3IgdmVjdG9yX2Jlc3Q7CiAgTnVtYmVyc0luTGlzdCAgIGxpc3Q7CiAgCiAgICAgIAogIHN0ZDo6Y291dCA8PCBuYnJfb2ZfcmFuZG9tcyA8PCAiLCAgIiA8PCBzdGQ6OmZsdXNoOwogIFRpbWVWYWx1ZSBsaXN0X3RpbWUgPSBsaW5lYXJJbnNlcnRQZXJmb3JtYW5jZSh2YWx1ZXMsIGxpc3QpOwogIFRpbWVWYWx1ZSB2ZWN0b3JfYmVzdF90aW1lID0gbGFzdFBvc2l0aW9uSW5zZXJ0aW9uUGVyZm9ybWFuY2UodmFsdWVzLCB2ZWN0b3JfYmVzdCk7CiAgVGltZVZhbHVlIHZlY3Rvcl93b3JzdF90aW1lID0gbGluZWFySW5zZXJ0UGVyZm9ybWFuY2UodmFsdWVzLCB2ZWN0b3Jfd29yc3QpOwogIHN0ZDo6Y291dCA8PCBsaXN0X3RpbWUgPDwgIiwgIiA8PCB2ZWN0b3JfYmVzdF90aW1lIDw8ICIsICIgPDwgdmVjdG9yX3dvcnN0X3RpbWUgPDwgIiAiIDw8IHN0ZDo6ZW5kbCA8PCBzdGQ6OmZsdXNoOwp9CgoKCgoKCmludCBtYWluKGludCBhcmdjLCBjaGFyKiogYXJndikKeyAKCiAgc3RkOjpjb3V0IDw8ICJQZXJoYXBzIHRoZSBtb3N0IGNvbW1vbiAnZGF0YSBjb2xsZWN0aW5nJyBvcGVyYXRpb24gaXMgcHV0dGluZyAnb25lIHBpZWNlIG9mIGRhdGEiIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQgPDwgIiAgaW4gZnJvbnQgb2YgYW4gb2xkZXIgcGllY2Ugb2YgZGF0YSBhbmQgc28gZm9ydGguXG4iIDw8IHN0ZDo6ZW5kbDsgCiAgc3RkOjpjb3V0IDw8ICJGb3IgbGlua2VkLWxpc3QgdGhpcyBpcyBpbnNlcnRpb24gYXQgaW5kZXggMFxuIiA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJGb3Igc3RkOjp2ZWN0b3IgIHRoZSAncHVzaCBhdCBmcm9udCcgb3BlcmF0aW9uIGlzIHdvcmtpbmcgYWdhaW5zdCBuYXR1cmUgb2YgdGhlICIgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCAgPDwgIiAgZGF0YSBzdHJ1Y3R1cmUgYW5kIGluIHRoaXMgY29tbW9uIHNjZW5hcmlvIHN1Y2ggdXNlIGlzIGNhbGxlZCAnbmFpdmUnXG4iIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQgPDwgIkZvciBzdGQ6OnZlY3RvciBpdCBpcyBuYXR1cmFsIGluIHRoaXMgc2NlbmFyaW8gdG8gd29yayBpbiB0aGUgZGlyZWN0aW9uIG9mICdncm93dGgnICIgPDwgc3RkOjplbmRsOyAKICBzdGQ6OmNvdXQgPDwgImkuZS4gcHVzaF9iYWNrLiBJdCBzb2x2ZXMgdGhlIHNhbWUgdGFzayBidXQgd29ya3MgYXMgaW50ZW5kZWQgd2l0aCB0aGUgbmF0dXJlIG9mIHRoZSAiIDw8IHN0ZDo6ZW5kbDsgCiAgc3RkOjpjb3V0IDw8ICIgIGRhdGEgc3RydWN0dXJlLlxuXG4iIDw8IHN0ZDo6ZW5kbDsgCgogIHN0ZDo6Y291dCA8PCAiZWxlbWVudHMsIGxpc3QsIHZlY3Rvcl9iZXN0LCB2ZWN0b3Jfd29yc3QobmFpdmUpIiA8PCBzdGQ6OmVuZGw7CiAgZzI6OlN0b3BXYXRjaCB3YXRjaDsKICBhZGRQZXJmb3JtYW5jZSgxMCk7CiAgYWRkUGVyZm9ybWFuY2UoMTAwKTsKICBhZGRQZXJmb3JtYW5jZSg1MDApOwogIGFkZFBlcmZvcm1hbmNlKDEwMDApOwogIGFkZFBlcmZvcm1hbmNlKDIwMDApOwogIGFkZFBlcmZvcm1hbmNlKDEwMDAwKTsKICBhZGRQZXJmb3JtYW5jZSgyMDAwMCk7CiAgYWRkUGVyZm9ybWFuY2UoNDAwMDApOwogIGFkZFBlcmZvcm1hbmNlKDEwMDAwMCk7CiAgLy8gbW9yZSB0aGFuIHRoaXMgd2lsbCB0aW1lb3V0IG9uIGlkZW9uZQogICAvLyBhZGRQZXJmb3JtYW5jZSg1MDAwMDApOwogIC8vYWRkUGVyZm9ybWFuY2UoMTAwMDAwMCk7CgogIGF1dG8gdG90YWxfdGltZV9tcyA9IHdhdGNoLmVsYXBzZWRNcygpLmNvdW50KCk7CiAgc3RkOjpjb3V0IDw8ICJFeGl0aW5nIHRlc3QsLiB0aGUgd2hvbGUgbWVhc3VyaW5nIHRvb2sgIiA8PCB0b3RhbF90aW1lX21zIDw8ICIgbWlsbGlzZWNvbmRzIjsKICBzdGQ6OmNvdXQgPDwgIiAoIiA8PCB0b3RhbF90aW1lX21zLzEwMDAgPDwgInNlY29uZHMgb3IgIiA8PCB0b3RhbF90aW1lX21zLygxMDAwKjYwKSA8PCAiIG1pbnV0ZXMpIiA8PCBzdGQ6OmVuZGw7IAogICByZXR1cm4gMDsKfQ==
-
upload with new input
-
result: Success time: 4.2s memory: 3068 kB returned value: 0
Perhaps the most common 'data collecting' operation is putting 'one piece of data in front of an older piece of data and so forth. For linked-list this is insertion at index 0 For std::vector the 'push at front' operation is working against nature of the data structure and in this common scenario such use is called 'naive' For std::vector it is natural in this scenario to work in the direction of 'growth' i.e. push_back. It solves the same task but works as intended with the nature of the data structure. elements, list, vector_best, vector_worst(naive) 10, 3, 6, 1 100, 7, 3, 13 500, 43, 7, 83 1000, 70, 10, 285 2000, 149, 27, 986 10000, 928, 159, 22613 20000, 1578, 284, 97330 40000, 3138, 582, 553636 100000, 7802, 1179, 3555756 Exiting test,. the whole measuring took 4266 milliseconds (4seconds or 0 minutes)


