#include <string>
#include <stdlib.h>
#include <sys/time.h>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <set>
#include <ext/hash_set>
#include <stx/btree_multiset.h>
#include <assert.h>
const unsigned int mininsertnum = 125;
const unsigned int maxinsertnum = 1024000 * 32;
const int randseed = 34234235;
const int min_nodeslots = 4;
const int max_nodeslots = 256;
inline double timestamp()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec * 0.000001;
}
BUG
template <int _innerslots, int _leafslots>
struct btree_traits_speed
{
static const bool selfverify = false;
static const bool debug = false;
static const int leafslots = _innerslots;
static const int innerslots = _leafslots;
};
struct Test_Set_Insert
{
typedef std::multiset<unsigned int> multiset_type;
Test_Set_Insert(unsigned int)
{
}
void run(unsigned int insertnum)
{
multiset_type set;
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.insert( rand() );
assert( set.size() == insertnum );
}
};
struct Test_Hashset_Insert
{
typedef __gnu_cxx::hash_multiset<unsigned int> multiset_type;
Test_Hashset_Insert(unsigned int)
{
}
void run(unsigned int insertnum)
{
multiset_type set;
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.insert( rand() );
assert( set.size() == insertnum );
}
};
template <int _slots>
struct Test_Btree_Insert
{
typedef stx::btree_multiset<unsigned int, std::less<unsigned int>,
struct btree_traits_speed<_slots, _slots> > btree_type;
Test_Btree_Insert(unsigned int)
{
}
void run(unsigned int insertnum)
{
btree_type bt;
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
bt.insert( rand() );
assert( bt.size() == insertnum );
}
};
struct Test_Set_InsertFindDelete
{
typedef std::multiset<unsigned int> multiset_type;
Test_Set_InsertFindDelete(unsigned int)
{
}
void run(unsigned int insertnum)
{
multiset_type set;
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.insert( rand() );
assert( set.size() == insertnum );
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.find(rand());
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.erase( set.find(rand()) );
assert( set.empty() );
}
};
struct Test_Hashset_InsertFindDelete
{
typedef __gnu_cxx::hash_multiset<unsigned int> multiset_type;
Test_Hashset_InsertFindDelete(unsigned int)
{
}
void run(unsigned int insertnum)
{
multiset_type set;
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.insert( rand() );
assert( set.size() == insertnum );
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.find(rand());
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.erase( set.find(rand()) );
assert( set.empty() );
}
};
template <int Slots>
struct Test_Btree_InsertFindDelete
{
typedef stx::btree_multiset<unsigned int, std::less<unsigned int>,
struct btree_traits_speed<Slots, Slots> > btree_type;
Test_Btree_InsertFindDelete(unsigned int)
{
}
void run(unsigned int insertnum)
{
btree_type bt;
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
bt.insert(rand());
assert( bt.size() == insertnum );
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
bt.exists(rand());
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
bt.erase_one(rand());
assert(bt.empty());
}
};
struct Test_Set_Find
{
typedef std::multiset<unsigned int> multiset_type;
multiset_type set;
Test_Set_Find(unsigned int insertnum)
{
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.insert( rand() );
assert( set.size() == insertnum );
}
void run(unsigned int insertnum)
{
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.find(rand());
}
};
struct Test_Hashset_Find
{
typedef __gnu_cxx::hash_multiset<unsigned int> multiset_type;
multiset_type set;
Test_Hashset_Find(unsigned int insertnum)
{
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.insert( rand() );
assert( set.size() == insertnum );
}
void run(unsigned int insertnum)
{
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
set.find(rand());
}
};
template <int Slots>
struct Test_Btree_Find
{
typedef stx::btree_multiset<unsigned int, std::less<unsigned int>,
struct btree_traits_speed<Slots, Slots> > btree_type;
btree_type bt;
Test_Btree_Find(unsigned int insertnum)
{
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
bt.insert(rand());
assert( bt.size() == insertnum );
}
void run(unsigned int insertnum)
{
srand(randseed);
for(unsigned int i = 0; i < insertnum; i++)
bt.exists(rand());
}
};
unsigned int repeatuntil;
template <typename TestClass>
void testrunner_loop(std::ostream& os, unsigned int insertnum)
{
unsigned int runs = 0;
double ts1, ts2;
do
{
runs = 0;
{
TestClass test(insertnum);
ts1 = timestamp();
for(unsigned int totaltests = 0; totaltests <= repeatuntil; totaltests += insertnum)
{
test.run(insertnum);
++runs;
}
ts2 = timestamp();
}
std::cerr << "Insert " << insertnum << " repeat " << (repeatuntil / insertnum) << " time " << (ts2 - ts1) << "\n";
if ((ts2 - ts1) < 1.0) repeatuntil *= 2;
}
while ((ts2 - ts1) < 1.0);
os << std::fixed << std::setprecision(10) << ((ts2 - ts1) / runs) << " " << std::flush;
}
template< template<int Slots> class functional, int Low, int High>
struct btree_range
{
inline void operator()(std::ostream& os, unsigned int insertnum)
{
testrunner_loop< functional<Low> >(os, insertnum);
btree_range<functional, Low+2, High>()(os, insertnum);
}
};
template< template<int Slots> class functional, int Low>
struct btree_range<functional, Low, Low>
{
inline void operator()(std::ostream& os, unsigned int insertnum)
{
testrunner_loop< functional<Low> >(os, insertnum);
}
};
int main()
{
{
std::ofstream os("speed-insert.txt");
repeatuntil = mininsertnum;
for(unsigned int insertnum = mininsertnum; insertnum <= maxinsertnum; insertnum *= 2)
{
std::cerr << "Insert " << insertnum << "\n";
os << insertnum << " " << std::flush;
testrunner_loop<Test_Set_Insert>(os, insertnum);
testrunner_loop<Test_Hashset_Insert>(os, insertnum);
btree_range<Test_Btree_Insert, min_nodeslots, max_nodeslots>()(os, insertnum);
os << "\n" << std::flush;
}
}
{
std::ofstream os("speed-all.txt");
repeatuntil = mininsertnum;
for(unsigned int insertnum = mininsertnum; insertnum <= maxinsertnum; insertnum *= 2)
{
std::cerr << "Insert, Find, Delete " << insertnum << "\n";
os << insertnum << " " << std::flush;
testrunner_loop<Test_Set_InsertFindDelete>(os, insertnum);
testrunner_loop<Test_Hashset_InsertFindDelete>(os, insertnum);
btree_range<Test_Btree_InsertFindDelete, min_nodeslots, max_nodeslots>()(os, insertnum);
os << "\n" << std::flush;
}
}
{
std::ofstream os("speed-find.txt");
repeatuntil = mininsertnum;
for(unsigned int insertnum = mininsertnum; insertnum <= maxinsertnum; insertnum *= 2)
{
std::cerr << "Find " << insertnum << "\n";
os << insertnum << " " << std::flush;
testrunner_loop<Test_Set_Find>(os, insertnum);
testrunner_loop<Test_Hashset_Find>(os, insertnum);
btree_range<Test_Btree_Find, min_nodeslots, max_nodeslots>()(os, insertnum);
os << "\n" << std::flush;
}
}
}