mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
417 lines
9.1 KiB
C++
417 lines
9.1 KiB
C++
#include "Flex.h"
|
|
#include <set>
|
|
#include <vector>
|
|
#include <list>
|
|
|
|
void Test(int N = 400)
|
|
{
|
|
Vector<int> a;
|
|
Flex<int> 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<int> a;
|
|
Flex<int> 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<int> a;
|
|
Flex<int> 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<int> a;
|
|
Vector<int> 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<int> 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<int> 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<int> 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<int> f;
|
|
for(int i = 0; i < N; i++)
|
|
f.Insert(rndpos[i], i);
|
|
}
|
|
Cout() << " Vector: " << tm << "\n";
|
|
LOG(" Vector: " << tm);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
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<T> 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<T> 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<T> set;
|
|
for(int i = 0; i < elements; i++)
|
|
set.FindAdd(rndpos[i]);
|
|
}
|
|
RLOG("Index FindAdd: " << tm.Elapsed());
|
|
Index<T> 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<T> sset;
|
|
for(int i = 0; i < elements; i++)
|
|
sset.insert(rndpos[i]);
|
|
}
|
|
RLOG("tree insert: " << tm.Elapsed() << "ms");
|
|
std::set<T> 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<int>(rndpos);
|
|
Buffer<String> rnd(10000000);
|
|
for(int i = 0; i < 10000000; i++)
|
|
rnd[i] = AsString(rndpos[i]);
|
|
RLOG("========= String");
|
|
SetBench<String>(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 <class T>
|
|
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<int> 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<T> 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<T> 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<T> 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<int>(0);
|
|
VppLog() << "\n\nString";
|
|
InsertBench<String>(String("01234567890123456789"));
|
|
}
|
|
|
|
void IterateBenchmark()
|
|
{
|
|
int elements = 10000000;
|
|
int N = 10;
|
|
while(elements > 0) {
|
|
RLOG(elements << "(" << N << "x)");
|
|
Flex<int> a;
|
|
Vector<int> b;
|
|
Array<int> c;
|
|
std::list<int> 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<int>::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;
|
|
}
|