什么被认为是按顺序推送某物的最佳数据结构(因此在任何位置插入,能够找到正确的位置),按顺序迭代,并从顶部弹出 N 个元素(因此 N 个最小元素,N 通过与阈值)?推送和弹出需要特别快(运行循环的每次迭代),而数据的有序完整迭代以可变速率发生,但频率可能少一个数量级。数据不能被完全迭代清除,它需要保持不变。所有被推送的东西最终都会被弹出,但是由于弹出可以删除多个元素,所以推送可能比弹出更多。任何时候结构中的数据规模可能高达数百或数千个元素。
我目前正在使用std::deque
二分搜索按升序插入元素。分析表明它占用了大部分时间,所以必须改变一些东西。 std::priority_queue
不允许迭代,我见过的黑客不会按顺序迭代。即使在有限的测试中(没有完整的迭代!),该std::set
课程的表现也比我的std::deque
方法差。
我搞砸的所有类似乎都没有考虑到这个用例。如果由于某种原因在 STL 或 boost 中找不到数据结构,我不反对创建自己的类。
编辑:
现在有两个主要功能,push
和prune
。 push
使用 65% 的时间,prune
使用 32%。使用的大部分时间push
是由于插入deque
(65% 中的 64%)。只有 1% 来自二分查找来寻找位置。
template<typename T, size_t Axes>
void Splitter<T, Axes>::SortedData::push(const Data& data) //65% of processing
{
size_t index = find(data.values[(axis * 2) + 1]);
this->data.insert(this->data.begin() + index, data); //64% of all processing happens here
}
template<typename T, size_t Axes>
void Splitter<T, Axes>::SortedData::prune(T value) //32% of processing
{
auto top = data.begin(), end = data.end(), it = top;
for (; it != end; ++it)
{
Data& data = *it;
if (data.values[(axis * 2) + 1] > value) break;
}
data.erase(top, it);
}
template<typename T, size_t Axes>
size_t Splitter<T, Axes>::SortedData::find(T value)
{
size_t start = 0;
size_t end = this->data.size();
if (!end) return 0;
size_t diff;
while (diff = (end - start) >> 1)
{
size_t mid = diff + start;
if (this->data[mid].values[(axis * 2) + 1] <= value)
{
start = mid;
}
else
{
end = mid;
}
}
return this->data[start].values[(axis * 2) + 1] <= value ? end : start;
}