我正在写一个树容器(只是为了理解和培训),现在我得到了第一个和非常基本的方法来添加元素到树中。可怜的树增加性能
这是知道我的树码。现在没有析构函数,没有清理和元素访问。
template <class T> class set
{
public:
struct Node
{
Node(const T& val)
: left(0), right(0), value(val)
{}
Node* left;
Node* right;
T value;
};
set()
{}
template <class T> void add(const T& value)
{
if (m_Root == nullptr)
{
m_Root = new Node(value);
}
Node* next = nullptr;
Node* current = m_Root;
do
{
if (next != nullptr)
{
current = next;
}
next = value >= current->value ? current->left : current->right;
} while (next != nullptr);
value >= current->value ? current->left = new Node(value) : current->right = new Node(value);
}
private:
Node* m_Root;
};
好了,现在我测试对一个std ::设置有独特的平衡(高)值的插入性能的附加性能,得出的结论是,性能很简单可怕。
是否有一个原因,为什么该集插入值快得多,以及什么样的方式来改善我的方法的插入性能? (我知道可能有更好的树模型,但据我所知,插入性能应该在大多数树模型之间靠近)。
在i5 4570股票时钟下, std :: set需要0.013s才能添加1000000个int16值。 我的设置需要4.5s来添加相同的值。
这个差别从哪里来?
更新:
还好吧,这里是我的testcode:
int main()
{
int n = 1000000;
test::set<test::int16> mset; //my set
std::set<test::int16> sset; //std set
std::timer timer; //simple wrapper for clock()
test::random_engine engine(0, 500000); //simple wrapper for rand() and yes, it's seeded, and yes I am aware that an int16 will overflow
std::set<test::int16> values; //Set of values to ensure unique values
bool flip = false;
for (int i = 0; n > i; ++i)
{
values.insert(flip ? engine.generate() : 0 - engine.generate());
flip = !flip; //ensure that we get high and low values and no straight line, but at least 2 paths
}
timer.start();
for (std::set<test::int16>::iterator it = values.begin(); values.end() != it; ++it)
{
mset.add(*it);
}
timer.stop();
std::cout << timer.totalTime() << "s for mset\n";
timer.reset();
timer.start();
for (std::set<test::int16>::iterator it = values.begin(); values.end() != it; ++it)
{
sset.insert(*it);
}
timer.stop();
std::cout << timer.totalTime() << "s for std\n";
}
设定就不会在每次值存储由于dubicates但两个容器会得到相同的高数量和相同的价值观为了确保代表性的结果。我知道测试可能会更准确,但它应该给出一些可比数字。
你用过优化的建立? –
@Guillaume Racicot是,全面优化 – Mango
你应该提供测试代码。如果你为你的树添加唯一值,它将退化为一个单链表。所以插入成本O(n)而不是O(log(n)) – max