Why is boost sg_set so slow on ordered insertions?

M

Melzzzzz

I have measured my implementation of scapegoat tree and boost's.
Surprisingly boost seems to choke on ordered data set insertion.
Yes, scapegoat trees are slowest on ordered insertion, because
of their nature, but *this* slow something must be wrong...

This is time for just 100k ordered elements insertion!
bmaxa@maxa:~/shootout/trees$ time ./boosintr
boost sg_set 14.94 size 100000
my scapegoat 0.06 size 100000

real 0m15.027s
user 0m14.965s
sys 0m0.056s

bench program taken and modified from boosts page about sg_sets:
#include <boost/intrusive/sg_set.hpp>
#include <vector>
#include <algorithm>
#include <cassert>
#include "ScapeGoat.h"

using namespace boost::intrusive;

class MyClass : public bs_set_base_hook<>
{
int int_;

public:
//This is a member hook
bs_set_member_hook<> member_hook_;

MyClass(int i)
: int_(i)
{}
friend bool operator< (const MyClass &a, const MyClass &b)
{ return a.int_ < b.int_; }
friend bool operator> (const MyClass &a, const MyClass &b)
{ return a.int_ > b.int_; }
friend bool operator== (const MyClass &a, const MyClass &b)
{ return a.int_ == b.int_; }
};

//Define an sg_set using the base hook that will store values in reverse order
//and won't execute floating point operations.
typedef sg_set
< MyClass > BaseSet;

int main()
{
typedef std::vector<MyClass>::iterator VectIt;
typedef std::vector<MyClass>::reverse_iterator VectRit;

//Create several MyClass objects, each one with a different value
std::vector<MyClass> values;
for(int i = 0; i < 100000; ++i) values.push_back(MyClass(i));
//std::random_shuffle(values.begin(),values.end());
BaseSet baseset;
ScapeGoat<MyClass,int> goat;

clock_t begin,end;
begin = clock();
for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
baseset.insert(*it);
}
end = clock();
std::cout<<"boost sg_set "<<((end-begin)/double(CLOCKS_PER_SEC))
<<" size "<<baseset.size()<<"\n";
begin = clock();
for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
goat.insert(std::make_pair(*it,0));
}
end = clock();
std::cout<<"my scapegoat "<<((end-begin)/double(CLOCKS_PER_SEC))
<<" size "<<goat.size()<<"\n";
//Now test sg_sets
{
BaseSet::iterator bit(baseset.begin()), bitend(baseset.end());
VectIt it(values.begin()), itend(values.end());
ScapeGoat<MyClass,int>::iterator sgi = goat.begin();

//Test the objects inserted in the base hook sg_set
for(; it != itend; ++it, ++bit)
assert(&*bit == &*it);

//Test the objects inserted in the member hook sg_set
for(it = values.begin(); it != itend; ++it, ++sgi)
assert(sgi->first == *it) ;
}
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top