ultimatepp/uppdev/Flex/Flex.cpp
cxl 351994a6cc Adding uppdev....
git-svn-id: svn://ultimatepp.org/upp/trunk@328 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-08-15 08:36:24 +00:00

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;
}