【发布时间】:2012-09-23 11:34:09
【问题描述】:
我刚刚发现,与使用预分配数组的“自制”堆栈版本相比,标准 std deque 真的很慢。
这是我的堆栈代码:
template <class T>
class FastStack
{
public:
T* st;
int allocationSize;
int lastIndex;
public:
FastStack(int stackSize);
FastStack();
~FastStack();
inline void resize(int newSize);
inline void push(T x);
inline void pop();
inline T getAndRemove();
inline T getLast();
inline void clear();
};
template <class T>
FastStack<T>::FastStack()
{
lastIndex = -1;
st = NULL;
}
template <class T>
FastStack<T>::FastStack(int stackSize)
{
st = NULL;
this->allocationSize = stackSize;
st = new T[stackSize];
lastIndex = -1;
}
template <class T>
FastStack<T>::~FastStack()
{
delete [] st;
}
template <class T>
void FastStack<T>::clear()
{
lastIndex = -1;
}
template <class T>
T FastStack<T>::getLast()
{
return st[lastIndex];
}
template <class T>
T FastStack<T>::getAndRemove()
{
return st[lastIndex--];
}
template <class T>
void FastStack<T>::pop()
{
--lastIndex;
}
template <class T>
void FastStack<T>::push(T x)
{
st[++lastIndex] = x;
}
template <class T>
void FastStack<T>::resize(int newSize)
{
if (st != NULL)
delete [] st;
st = new T[newSize];
}
.
我为双端队列运行这个简单的基准测试:
std::deque<int> aStack;
int x;
HRTimer timer;
timer.Start();
for (int i = 0; i < 2000000000; i++)
{
aStack.push_back(i);
x = aStack.back();
if (i % 100 == 0 && i != 0)
for (int j = 0; j < 100; j++)
aStack.pop_back();
}
double totalTime = timer.Stop();
stringstream ss;
ss << "std::deque " << totalTime;
log(ss.str());
.
使用带有向量的 std 堆栈作为容器(正如“Michael Kohne”所建议的那样)
std::stack<int, std::vector<int>> bStack;
int x;
HRTimer timer;
timer.Start();
for (int i = 0; i < 2000000000; i++)
{
bStack.push(i);
x = bStack.top();
if (i % 100 == 0 && i != 0)
for (int j = 0; j < 100; j++)
bStack.pop();
}
double totalTime = timer.Stop();
stringstream ss;
ss << "std::stack " << totalTime;
log(ss.str());
.
我的 FastStack 也是如此:
FastStack<int> fstack(200);
int x;
HRTimer timer;
timer.Start();
for (int i = 0; i < 2000000000; i++)
{
fstack.push(i);
x = fstack.getLast();
if (i % 100 == 0 && i != 0)
for (int j = 0; j < 100; j++)
fstack.pop();
}
double totalTime = timer.Stop();
stringstream ss;
ss << "FastStack " << totalTime;
log(ss.str());
.
4次运行后的结果如下:
双端队列 15.529
双端队列 15.3756
双端队列 15.429
双端队列 15.4778
堆栈 6.19099
堆栈 6.1834
堆栈 6.19315
堆栈 6.19841
FastStack 3.01085
FastStack 2.9934
FastStack 3.02536
快速堆栈 3.00937
结果以秒为单位,我在 Intel i5 3570k(默认时钟)上运行代码。我使用了具有所有可用优化的 VS2010 编译器。
我知道我的 FastStack 有很多限制,但是在很多情况下,可以使用它以及何时可以提供很好的提升! (我在一个项目中使用了它,与 std::queue 相比,我的速度提高了 2 倍)。
所以现在我的问题是:C++ 中是否还有其他人人都在使用但没人知道的“抑制剂”?
编辑:我不想冒犯,我只是好奇你是否知道一些像这样的未知“加速”。
【问题讨论】:
-
构建双端队列后,在其上调用resize。看看它是否会产生很大的速度差异。我的猜测是,获得/损失的速度的很大一部分来自试图通过改变大小来“智能”管理内存的双端队列类。
-
如果“没有人知道他们”如何在这里举报?
-
我会假装我没有看到您的最后一句话,并将其视为合法的性能问题。
-
您的“堆栈”不提供随机访问或两端的快速插入。这是一个明智的比较吗?我敢肯定你的丰田汽车比我的油箱需要更少的燃料,而且它没有大炮。
-
std::deque设计用于在两端进行恒定时间插入。更公平的比较是扩展您的堆栈类(当然,它不再是堆栈)以允许这样做。或者与std::vector比较。
标签: c++ performance stack deque