<http://www.gnu.org/licenses/>
#include <string>
#include <stdlib.h>
#include <sys/time.h>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <set>
#include <ext/hash_set>
#include <tr1/unordered_set>
#include <stx/btree_multiset.h>
#include <map>
#include <ext/hash_map>
#include <tr1/unordered_map>
#include <stx/btree_multimap.h>
#include <assert.h>
const unsigned int minitems = 125;
const unsigned int maxitems = 1024000 * 64;
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 : stx::btree_default_set_traits<unsigned int>
{
static const bool selfverify = false;
static const bool debug = false;
static const int leafslots = _innerslots;
static const int innerslots = _leafslots;
static const size_t binsearch_threshold = 256*1024*1024;
};
template <typename SetType>
struct Test_Set_Insert
{
Test_Set_Insert(unsigned int) {}
inline void run(unsigned int items)
{
SetType set;
srand(randseed);
for(unsigned int i = 0; i < items; i++)
set.insert( rand() );
assert( set.size() == items );
}
};
template <typename SetType>
struct Test_Set_InsertFindDelete
{
Test_Set_InsertFindDelete(unsigned int) {}
inline void run(unsigned int items)
{
SetType set;
srand(randseed);
for(unsigned int i = 0; i < items; i++)
set.insert( rand() );
assert( set.size() == items );
srand(randseed);
for(unsigned int i = 0; i < items; i++)
set.find(rand());
srand(randseed);
for(unsigned int i = 0; i < items; i++)
set.erase( set.find(rand()) );
assert( set.empty() );
}
};
template <typename SetType>
struct Test_Set_Find
{
SetType set;
Test_Set_Find(unsigned int items)
{
srand(randseed);
for(unsigned int i = 0; i < items; i++)
set.insert( rand() );
assert( set.size() == items );
}
void run(unsigned int items)
{
srand(randseed);
for(unsigned int i = 0; i < items; i++)
set.find(rand());
}
};
template < template<typename SetType> class TestClass >
struct TestFactory_Set
{
typedef TestClass< std::multiset<unsigned int> > StdSet;
typedef TestClass< __gnu_cxx::hash_multiset<unsigned int> > HashSet;
typedef TestClass< std::tr1::unordered_multiset<unsigned int> > UnorderedSet;
template <int Slots>
struct BtreeSet
: TestClass< stx::btree_multiset<unsigned int, std::less<unsigned int>,
struct btree_traits_speed<Slots, Slots> > >
{
BtreeSet(unsigned int n)
: TestClass< stx::btree_multiset<unsigned int, std::less<unsigned int>,
struct btree_traits_speed<Slots, Slots> > >(n) {}
};
void call_testrunner(std::ostream& os, unsigned int items);
};
template <typename MapType>
struct Test_Map_Insert
{
Test_Map_Insert(unsigned int) {}
inline void run(unsigned int items)
{
MapType map;
srand(randseed);
for(unsigned int i = 0; i < items; i++) {
unsigned int r = rand();
map.insert( std::make_pair(r,r) );
}
assert( map.size() == items );
}
};
template <typename MapType>
struct Test_Map_InsertFindDelete
{
Test_Map_InsertFindDelete(unsigned int) {}
inline void run(unsigned int items)
{
MapType map;
srand(randseed);
for(unsigned int i = 0; i < items; i++) {
unsigned int r = rand();
map.insert( std::make_pair(r,r) );
}
assert( map.size() == items );
srand(randseed);
for(unsigned int i = 0; i < items; i++)
map.find(rand());
srand(randseed);
for(unsigned int i = 0; i < items; i++)
map.erase( map.find(rand()) );
assert( map.empty() );
}
};
template <typename MapType>
struct Test_Map_Find
{
MapType map;
Test_Map_Find(unsigned int items)
{
srand(randseed);
for(unsigned int i = 0; i < items; i++) {
unsigned int r = rand();
map.insert( std::make_pair(r,r) );
}
assert( map.size() == items );
}
void run(unsigned int items)
{
srand(randseed);
for(unsigned int i = 0; i < items; i++)
map.find(rand());
}
};
template < template<typename MapType> class TestClass >
struct TestFactory_Map
{
typedef TestClass< std::multimap<unsigned int, unsigned int> > StdMap;
typedef TestClass< __gnu_cxx::hash_multimap<unsigned int, unsigned int> > HashMap;
typedef TestClass< std::tr1::unordered_multimap<unsigned int, unsigned int> > UnorderedMap;
template <int Slots>
struct BtreeMap
: TestClass< stx::btree_multimap<unsigned int, unsigned int, std::less<unsigned int>,
struct btree_traits_speed<Slots, Slots> > >
{
BtreeMap(unsigned int n)
: TestClass< stx::btree_multimap<unsigned int, unsigned int, std::less<unsigned int>,
struct btree_traits_speed<Slots, Slots> > >(n) {}
};
void call_testrunner(std::ostream& os, unsigned int items);
};
unsigned int repeatuntil;
template <typename TestClass>
void testrunner_loop(std::ostream& os, unsigned int items)
{
unsigned int runs = 0;
double ts1, ts2;
do
{
runs = 0;
{
TestClass test(items);
ts1 = timestamp();
for(unsigned int totaltests = 0; totaltests <= repeatuntil; totaltests += items)
{
test.run(items);
++runs;
}
ts2 = timestamp();
}
std::cerr << "Insert " << items << " repeat " << (repeatuntil / items)
<< " 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 items)
{
testrunner_loop< functional<Low> >(os, items);
btree_range<functional, Low+2, High>()(os, items);
}
};
template< template<int Slots> class functional, int Low>
struct btree_range<functional, Low, Low>
{
inline void operator()(std::ostream& os, unsigned int items)
{
testrunner_loop< functional<Low> >(os, items);
}
};
template < template<typename Type> class TestClass >
void TestFactory_Set<TestClass>::call_testrunner(std::ostream& os, unsigned int items)
{
os << items << " " << std::flush;
testrunner_loop<StdSet>(os, items);
testrunner_loop<HashSet>(os, items);
testrunner_loop<UnorderedSet>(os, items);
#if 1
btree_range<BtreeSet, min_nodeslots, max_nodeslots>()(os, items);
#else
testrunner_loop< BtreeSet<4> >(os, items);
for (int i = 6; i < 8; i+=2) os << "0 ";
testrunner_loop< BtreeSet<8> >(os, items);
for (int i = 10; i < 16; i+=2) os << "0 ";
testrunner_loop< BtreeSet<16> >(os, items);
for (int i = 18; i < 32; i+=2) os << "0 ";
testrunner_loop< BtreeSet<32> >(os, items);
for (int i = 34; i < 64; i+=2) os << "0 ";
testrunner_loop< BtreeSet<64> >(os, items);
for (int i = 66; i < 128; i+=2) os << "0 ";
testrunner_loop< BtreeSet<128> >(os, items);
for (int i = 130; i < 256; i+=2) os << "0 ";
testrunner_loop< BtreeSet<256> >(os, items);
#endif
os << "\n" << std::flush;
}
template < template<typename Type> class TestClass >
void TestFactory_Map<TestClass>::call_testrunner(std::ostream& os, unsigned int items)
{
os << items << " " << std::flush;
testrunner_loop<StdMap>(os, items);
testrunner_loop<HashMap>(os, items);
testrunner_loop<UnorderedMap>(os, items);
#if 1
btree_range<BtreeMap, min_nodeslots, max_nodeslots>()(os, items);
#else
testrunner_loop< BtreeMap<4> >(os, items);
for (int i = 6; i < 8; i+=2) os << "0 ";
testrunner_loop< BtreeMap<8> >(os, items);
for (int i = 10; i < 16; i+=2) os << "0 ";
testrunner_loop< BtreeMap<16> >(os, items);
for (int i = 18; i < 32; i+=2) os << "0 ";
testrunner_loop< BtreeMap<32> >(os, items);
for (int i = 34; i < 64; i+=2) os << "0 ";
testrunner_loop< BtreeMap<64> >(os, items);
for (int i = 66; i < 128; i+=2) os << "0 ";
testrunner_loop< BtreeMap<128> >(os, items);
for (int i = 130; i < 256; i+=2) os << "0 ";
testrunner_loop< BtreeMap<256> >(os, items);
#endif
os << "\n" << std::flush;
}
int main()
{
{
std::ofstream os("speed-set-insert.txt");
repeatuntil = minitems;
for(unsigned int items = minitems; items <= maxitems; items *= 2)
{
std::cerr << "set: insert " << items << "\n";
TestFactory_Set<Test_Set_Insert>().call_testrunner(os, items);
}
}
{
std::ofstream os("speed-set-all.txt");
repeatuntil = minitems;
for(unsigned int items = minitems; items <= maxitems; items *= 2)
{
std::cerr << "set: insert, find, delete " << items << "\n";
TestFactory_Set<Test_Set_InsertFindDelete>().call_testrunner(os, items);
}
}
{
std::ofstream os("speed-set-find.txt");
repeatuntil = minitems;
for(unsigned int items = minitems; items <= maxitems; items *= 2)
{
std::cerr << "set: find " << items << "\n";
TestFactory_Set<Test_Set_Find>().call_testrunner(os, items);
}
}
{
std::ofstream os("speed-map-insert.txt");
repeatuntil = minitems;
for(unsigned int items = minitems; items <= maxitems; items *= 2)
{
std::cerr << "map: insert " << items << "\n";
TestFactory_Map<Test_Map_Insert>().call_testrunner(os, items);
}
}
{
std::ofstream os("speed-map-all.txt");
repeatuntil = minitems;
for(unsigned int items = minitems; items <= maxitems; items *= 2)
{
std::cerr << "map: insert, find, delete " << items << "\n";
TestFactory_Map<Test_Map_InsertFindDelete>().call_testrunner(os, items);
}
}
{
std::ofstream os("speed-map-find.txt");
repeatuntil = minitems;
for(unsigned int items = minitems; items <= maxitems; items *= 2)
{
std::cerr << "map: find " << items << "\n";
TestFactory_Map<Test_Map_Find>().call_testrunner(os, items);
}
}
return 0;
}