Я просто узнал, что стандартный std-deque действительно медленный, если сравнивать с моей «самодельной» версией стека, которые используют предварительно выделенный массив.
Это код моего стека: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());
.
Использование зЬй стек с вектором в качестве контейнера (как 'Майкл Köhne' предложил)
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 серий заключаются в следующем:
Deque 15,529
Deque 15,3756
Deque 15,429
Deque 15,4778
стек 6,19099
стек 6,1834
стек 6,19315
стек 6,19841
FastStack 3.01085
FastStack 2,9934
FastStack 3,02536
FastStack 3,00937
Результаты в секундах, и я был запущен код на 3570k Intel i5 (по часам по умолчанию). Я использовал компилятор VS2010 со всеми имеющимися оптимизациями. Я знаю, что у моего FastStack есть много ограничений, но есть много ситуаций, где он может быть использован, и когда он может дать хороший импульс! (Я использовал его в одном проекте, где я получаю 2x ускорение по сравнению с std :: queue).
Итак, теперь мой вопрос:
Есть ли в C++ другие «ингибиторы», которые все используют, но никто не знает о них?
EDIT: Я не хочу быть оскорбительным, мне просто интересно, если вы знаете некоторые неизвестные «ускорения», подобные этому.
Вопрос о списке «ингибиторов», подобных этому, не является конструктивным. – nhahtdh
После того, как вы построите deque, назовите [изменить размер] (http://www.cplusplus.com/reference/stl/deque/resize/). Посмотрите, если это делает большую разницу в скорости. Я предполагаю, что большая часть скорости, полученной/потерянной, принадлежит классу deque, который пытается «умно» управлять памятью, изменяя размер. –
Вам не хватает фигурных скобок в инструкции if. – Rapptz