Как определиться с распределением стека и кучи против boost :: pool в таком случае? - PullRequest
3 голосов
/ 07 июня 2011

У меня есть класс, который использует Boost :: Вариант для хранения двойной или строки, например:

class value
{
  boost::variant<double, std::string> val;
};

Это должен быть неизменный тип значения для игрушечного переводчика, с которым я играю. Сначала казалось хорошей идеей передавать его по константной ссылке и возвращать по значению и всегда размещать его в стеке, поскольку я хотел, чтобы он рассматривался как примитив. Однако потом я увидел, что его размер составляет 40 байт (в основном из-за размера std :: string), и я немного волновался. Я знаю, что не должен выделять большие куски памяти в стеке, но насколько большой слишком большой?

Кроме того, копирование 40 байт каждый раз, когда я возвращаюсь, тем более что значение является неизменным и даже копировать его не нужно, кажется немного расточительством.

Опция регулярного выделения кучи не кажется слишком привлекательной, поскольку у меня может быть тысячи таких распределений / освобождений в секунду.

Последний вариант, который я придумал, это иметь boost :: pool для выделения этих объектов при необходимости и использовать boost :: shared_ptr для управления их временем жизни. Однако, поскольку интерпретатор отвечает за выделение памяти (тип выделения памяти будет политикой, передаваемой интерпретатору в качестве аргумента шаблона), это будет означать, что класс значения должен знать о интерпретаторе, что немного усложняет ситуацию. .

Итак, вот вопросы:

  • Что мне делать в этом случае и почему?
  • Насколько большой «слишком большой» для размещения в стеке? Я уверен, что это зависит от того, как часто оно выделяется и как часто его нужно копировать.

Спасибо.

Ответы [ 2 ]

4 голосов
/ 07 июня 2011
  • Что мне делать в этом случае и почему?

Как всегда, напишите программу, чтобы ее было легче понять. Если профилирование позже обнаружит, что это действительно проблема, вы всегда можете позже превратить value::val в некоторый динамически размещенный объект. (Конечно, это предполагает, что val будет достаточно хорошо абстрагировано, чтобы не влиять на клиентов класса.)

  • Насколько большой «слишком большой» для размещения в стеке? Я уверен, что это зависит от того, как часто он распределяется и как часто его нужно копировать.

Это также зависит от того, на какой платформе вы находитесь. Мы говорим о 8-битном встроенном чипе, работающем на вашем тостере или 64-битной рабочей станции?
ИМО, в конце концов, сводится к следующему: Слишком большой, если он создает проблемы из-за его размера.

0 голосов
/ 07 июня 2011

Если вам действительно нужно оптимизировать это, я бы порекомендовал не использовать std::string в Windows.

Для неизменяемых строк - реализация, подобная копированию при записи (в основном, все копии строки разделяюттот же самый внутренний буфер) может быть легко реализован поверх shared_ptr.

Поскольку с тех пор вам потребуется только один указатель в вашем классе ConstString, вам не придется беспокоиться о передаче по копии.

...