Есть ли способ уменьшить количество Malloc / free? - PullRequest
8 голосов
/ 01 марта 2010

Я пишу встроенное приложение. В некоторых местах я часто использую std :: ostringstream, так как это очень удобно для моих целей. Тем не менее, я только что обнаружил, что снижение производительности является чрезвычайным, поскольку добавление данных в поток приводит к большому количеству обращений к malloc и free. Есть ли способ избежать этого?

Моей первой мыслью было сделать статический поток ostringstream и сбросить его с помощью ostringstream :: set (""). Тем не менее, это не может быть сделано, так как мне нужны функции для повторного входа.

Ответы [ 4 ]

2 голосов
/ 01 марта 2010

Вероятно, утвержденный способ справиться с этим - создать собственный объект basic_stringbuf для использования с ostringstream. Для этого у вас есть пара вариантов. Можно было бы использовать буфер фиксированного размера, и overflow просто потерпит неудачу, когда / если вы попытаетесь создать слишком длинный вывод. Другая возможность - использовать вектор в качестве буфера. В отличие от std :: string, вектор гарантирует, что добавляемые данные будут амортизироваться постоянной сложностью. Кроме того, он никогда не освобождает данные из буфера, если вы не принудительно их используете, поэтому обычно он увеличивается до максимального размера, с которым вы имеете дело. С этого момента он не должен выделять или освобождать память, если вы не создадите строку, длина которой превышает имеющуюся в данный момент.

2 голосов
/ 01 марта 2010

Ну, Booger решение было бы переключиться на sprintf(). Это небезопасно и подвержено ошибкам, но часто быстрее.

Не всегда, хотя. Мы не можем использовать его (или ostringstream) на моей работе в реальном времени после инициализации, потому что выполняем как выделение памяти, так и освобождение.

Наш способ решения этой проблемы - перепрыгнуть через множество обручей, чтобы убедиться, что мы выполняем все преобразования строк при запуске (когда нам еще не нужно быть в режиме реального времени). Я думаю, что была одна ситуация, когда мы записали наш собственный конвертер в массив с фиксированным размером, выделенным из стека. У нас есть некоторые ограничения по размеру, на которые мы можем рассчитывать для конкретных конверсий.

Для более общего решения вы можете рассмотреть возможность написания своей собственной версии ostringstream, которая использует буфер фиксированного размера (с проверкой ошибок на границах, разумеется, в пределах). Это было бы немного работы, но если у вас есть много этих потоковых операций, это может стоить того.

2 голосов
/ 01 марта 2010

Если вы знаете, насколько велики данные перед созданием потока, вы можете использовать ostrstream, конструктор которого может принимать буфер в качестве параметра. Таким образом, не будет никакого управления памятью данных.

1 голос
/ 02 марта 2010

std::ostringsteam - это удобный интерфейс. Он связывает std::string с std::ostream, предоставляя пользовательский std::streambuf. Вы можете реализовать свой собственный std :: streambuf. Это позволяет вам сделать все управление памятью. Вы по-прежнему получаете хорошее форматирование std::ostream, но у вас есть полный контроль над управлением памятью. Конечно, следствием этого является то, что вы получаете отформатированный вывод в char[] - но это, вероятно, не большая проблема, если вы являетесь разработчиком встроенных программ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...