#include "Flex.h" #include #include #include void Test(int N = 400) { Vector a; Flex b; for(int i = 0; i < N; i++) { int pos = i ? rand() % i : 0; a.Insert(pos, i); b.Insert(pos, i); for(int j = 0; j <= i; j++) if(a[j] != b[j]) { DUMPC(a); DUMP(j); for(int q = 0; q <= i; q++) LOG(q << ": " << b[q]); Panic("Panic!"); } if(i % 2000 == 0) Cout() << i << "\n"; } Cout() << "Passed!\n"; } void TestLowerBound() { Cout() << "Lower bound test\n"; Vector a; Flex b(2); for(int i = 0; i < 2000; i++) { ASSERT(a.GetCount() == b.GetCount()); for(int j = -i; j <= i; j++) { for(int k = -1; k <= 1; k++) { int vl = FindLowerBound(a, 2 * j + k); int fl = b.FindLowerBound(2 * j + k); if(vl != fl) { DUMP(2 * j); DUMP(k); DUMP(vl); DUMP(fl); DUMPC(a); for(int q = 0; q < b.GetCount(); q++) LOG(q << ": " << b[q]); Panic("Panic!"); } } } Cout() << i << "\n"; a.Insert(a.GetCount(), 2 * i); a.Insert(0, -2 * i); b.Insert(b.GetCount(), 2 * i); b.Insert(0, -2 * i); } Cout() << "Passed!\n"; } void TestUpperBound() { Vector a; Flex b(2); for(int i = 0; i < 20000; i++) { a.Insert(i, 2 * i); b.Insert(i, 2 * i); for(int j = 0; j <= i; j++) { for(int k = -1; k <= 1; k++) { int vl = FindUpperBound(a, 2 * j + k); int fl = b.FindUpperBound(2 * j + k); if(vl != fl) { DUMP(2 * j); DUMP(k); DUMP(vl); DUMP(fl); DUMPC(a); for(int q = 0; q <= i; q++) LOG(q << ": " << b[q]); Panic("Panic!"); } } } if(i % 2000 == 0) Cout() << i << "\n"; } Cout() << "Passed!\n"; } void TestMap() { Order a; Vector b; for(int i = 0; i < 100000; i++) { int q = rand(); a.FindAdd(q); int p = FindLowerBound(b, q); if(p >= b.GetCount() || b[p] != q) b.Insert(p, q); LOG(a.GetCount() << " " << b.GetCount()); if(a.GetCount() != b.GetCount()) { DUMP(q); DUMPC(b); for(int q = 0; q < a.GetCount(); q++) LOG(q << ": " << a[q]); Panic("Failed count!"); } for(int j = 0; j < b.GetCount(); j++) { if(a[j] != b[j]) { DUMP(q); DUMPC(b); for(int q = 0; q < a.GetCount(); q++) LOG(q << ": " << a[q]); Panic("Failed!"); } } if(i % 1000 == 0) Cout() << i << "\n"; } } static Buffer rndpos(100000000); void ScaleBench() { for(int N = 10; N < 20000000; N += N) { int M = max(1, 2000000 / N); Cout() << N << " elements\r\n"; RLOG(N << " elements"); for(int shift = 3; shift < 16; shift++) { TimeStop tm; for(int q = 0; q < M; q++) { Flex f(shift); for(int i = 0; i < N; i++) f.Insert(rndpos[i], i); } Cout() << " shift " << shift << ":" << tm << "\n"; RLOG(" shift " << shift << ":" << tm); } LOG("-----------------"); } return; } void VectorBench() { for(int N = 200; N < 200000; N += N) { int M = max(1, 2000000 / N); Cout() << N << " elements ( " << M << "x):\n"; LOG(N << " elements ( " << M << "x):"); { TimeStop tm; for(int q = 0; q < M; q++) { Flex f; for(int i = 0; i < N; i++) f.Insert(rndpos[i], i); } Cout() << " Flex: " << tm << "\n"; LOG(" Flex: " << tm); } { TimeStop tm; for(int q = 0; q < M; q++) { Vector f; for(int i = 0; i < N; i++) f.Insert(rndpos[i], i); } Cout() << " Vector: " << tm << "\n"; LOG(" Vector: " << tm); } } } template void SetBench(T *rndpos) { for(int elements = 10; elements < 10000000; elements += 3 * elements) { #ifdef _DEBUG int repeat = 1; #else int repeat = max(1, 10000000 / elements); #endif int count1, count2; RLOG("------ " << elements << " elements"); { TimeStop tm; String info; for(int q = 0; q < repeat; q++) { Order set; for(int i = 0; i < elements; i++) set.FindAdd(rndpos[i]); if(q == 0) info = set.GetInfo(); } RLOG("Order FindAdd: " << tm.Elapsed() << "ms, info: " << info); Order set; for(int i = 0; i < elements; i++) set.FindAdd(rndpos[i]); count1 = set.GetCount(); for(int i = 0; i < set.GetCount() - 1; i++) if(set[i] > set[i + 1]) Panic("BUG!"); TimeStop tm2; int xx; for(int q = 0; q < repeat; q++) { xx = 0; for(int i = 0; i < elements; i++) { if(set.Find(rndpos[i]) >= 0) xx++; } } RLOG("Order Find: " << tm2.Elapsed() << "ms, matches: " << xx); } { TimeStop tm; for(int q = 0; q < repeat; q++) { Index set; for(int i = 0; i < elements; i++) set.FindAdd(rndpos[i]); } RLOG("Index FindAdd: " << tm.Elapsed()); Index set; for(int i = 0; i < elements; i++) set.FindAdd(rndpos[i]); TimeStop tm2; int xx; for(int q = 0; q < repeat; q++) { xx = 0; for(int i = 0; i < elements; i++) { if(set.Find(rndpos[i]) >= 0) xx++; } } RLOG("Index Find: " << tm2.Elapsed() << "ms, matches: " << xx); } { TimeStop tm; for(int q = 0; q < repeat; q++) { std::set sset; for(int i = 0; i < elements; i++) sset.insert(rndpos[i]); } RLOG("tree insert: " << tm.Elapsed() << "ms"); std::set sset; for(int i = 0; i < elements; i++) sset.insert(rndpos[i]); count2 = sset.size(); TimeStop tm2; int xx; for(int q = 0; q < repeat; q++) { xx = 0; for(int i = 0; i < elements; i++) if(sset.find(rndpos[i]) != sset.end()) xx++; } RLOG("tree find: " << tm2.Elapsed() << "ms, matches: " << xx); } /* if(count1 != count2) { RDUMP(count1); RDUMP(count2); Panic("Failure!"); }*/ } } void SetBenchmark() { RLOG("========= int"); SetBench(rndpos); Buffer rnd(10000000); for(int i = 0; i < 10000000; i++) rnd[i] = AsString(rndpos[i]); RLOG("========= String"); SetBench(rnd); } String FillLeft(const String& text, int n) { int q = n - text.GetLength(); return q > 0 ? String(' ', q) + text : text; } String FillRight(const String& text, int n) { int q = n - text.GetLength(); return q > 0 ? text + String(' ', q) : text; } template void InsertBench(const T& data) { VppLog() << "\n" << FillRight("size (times)", 20) << FillLeft("std::vector", 12) << FillLeft("Vector", 12) << FillLeft("Flex", 12) << "\n"; for(int n = 10; n < 500000; n += n) { Buffer rnd(n); for(int q = 0; q < n; q++) rnd[q] = q ? (rand() + (rand() << 16)) % q : 0; int N = 1000000 / n; VppLog() << FillLeft(AsString(n), 7) << FillRight(" (" + AsString(N) + "x)", 13); T x = data; { TimeStop tm; for(int q = 0; q < N; q++) { std::vector v; for(int i = 0; i < n; i++) v.insert(v.begin() + rnd[i], x); } VppLog() << FillLeft(tm.ToString() + " s", 12); } { TimeStop tm; for(int q = 0; q < N; q++) { Vector v; for(int i = 0; i < n; i++) v.Insert(rnd[i], x); } VppLog() << FillLeft(tm.ToString() + " s", 12); } { TimeStop tm; for(int q = 0; q < N; q++) { Flex v; for(int i = 0; i < n; i++) v.Insert(rnd[i], x); } VppLog() << FillLeft(tm.ToString() + " s", 12); } VppLog() << "\n"; } } void InsertBenchmark() { VppLog() << "int\n"; InsertBench(0); VppLog() << "\n\nString"; InsertBench(String("01234567890123456789")); } void IterateBenchmark() { int elements = 10000000; int N = 10; while(elements > 0) { RLOG(elements << "(" << N << "x)"); Flex a; Vector b; Array c; std::list d; for(int i = 0; i < elements; i++) { a.Insert(a.GetCount(), i); b.Add(i); c.Add(i); d.push_back(i); } { TimeStop tm; unsigned sum = 0; for(int n = 0; n < N; n++) { sum = 0; for(int i = 0; i < a.GetCount(); i++) sum += a[i]; } RLOG("Flex " << tm << ", sum = " << sum); } { TimeStop tm; unsigned sum = 0; for(int n = 0; n < N; n++) { sum = 0; for(int i = 0; i < b.GetCount(); i++) sum += b[i]; } RLOG("Vector " << tm << ", sum = " << sum); } { TimeStop tm; unsigned sum = 0; for(int n = 0; n < N; n++) { sum = 0; for(int i = 0; i < c.GetCount(); i++) sum += c[i]; } RLOG("Array " << tm << ", sum = " << sum); } { TimeStop tm; unsigned sum = 0; for(int n = 0; n < N; n++) { sum = 0; for(std::list::iterator i = d.begin(); i != d.end(); i++) sum += *i; } RLOG("std::list " << tm << ", sum = " << sum); } elements /= 100; N *= 100; } } CONSOLE_APP_MAIN { // TestMap(); return; // Test(10000); return; // TestUpperBound(); return; // Test(400); TestLowerBound(); return; StdLogSetup(LOG_COUT|LOG_FILE); InsertBenchmark(); return; // IterateBenchmark(); return; for(int i = 0; i < 100000000; i++) { rndpos[i] = i ? (rand() + (rand() << 15)) : 0; } // SetBenchmark(); // Test(); return; // ScaleBench(); return; return; }