Единственный способ, с помощью которого std::stack
значительно медленнее, чем стек процессора, - это выделение памяти из свободного хранилища. По умолчанию он использует std::deque
для хранения, который распределяет память по частям по мере необходимости. До тех пор, пока вы не продолжите уничтожать и воссоздавать стек, он будет сохранять эту память и не должен выделять больше, если он не станет больше, чем раньше. Итак, структура кода выглядит так:
std::stack<int> stack;
for (int i = 0; i < HUGE_NUMBER; ++i)
do_lots_of_work(stack); // uses stack
вместо:
for (int i = 0; i < HUGE_NUMBER; ++i)
do_lots_of_work(); // creates its own stack
Если после профилирования вы обнаружите, что выделение памяти все еще занимает слишком много времени, вы можете предварительно выделить большой блок, поэтому при запуске программы вам потребуется только одно выделение (при условии, что вы можете найти верхний предел размера стека ). Для этого вам нужно попасть во внутренности стека, но это возможно, если вы получите собственный тип стека. Как то так (не проверено):
class PreallocatedStack : public std::stack< int, std::vector<int> >
{
public:
explicit PreallocatedStack(size_t size) { c.reserve(size); }
};
РЕДАКТИРОВАТЬ: это довольно ужасный хак, но он поддерживается стандартом C ++. Более вкусным было бы инициализировать стек зарезервированным вектором за счет дополнительного выделения. И не пытайтесь использовать этот класс полиморфно - контейнеры STL не предназначены для этого.
Использование стека процессоров не будет переносимым, и на некоторых платформах может быть невозможно использовать локальные переменные после нажатия чего-либо - вам может понадобиться закодировать все в сборке. (Это вариант, если вам действительно нужно считать каждый последний цикл и вам не нужна переносимость, но убедитесь, что вы используете профилировщик, чтобы убедиться, что он действительно стоит). Нет никакого способа использовать стек другого потока, который будет быстрее, чем контейнер стека.