2010-03-01 4 views
8

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

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

+0

Dupe http://stackoverflow.com/questions/1941064/should-i-preallocate-stdstringstream –

+0

Хм ... вопрос об ошибке не дает правильного ответа. –

+0

Кроме того, «dupe» предварительно принимает ответ. – MSalters

ответ

2

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

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

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

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

+0

Что вы используете вместо этого? –

+0

Я начал добавлять это, но отступил. Я пойду вперед и поставлю его для вас. –

+0

Вы могли бы хотя бы использовать snprintf (с буфером стека), но я до сих пор не буду защищать это, если профилирование не показывает, что оно дает вам преимущество, и вы решаете, что недостатки стоит его использовать. –

2

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

2

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

+0

Я проверил источник реализации STL, который я использую, если передать ему строку в конструктор ostringstream, он просто делает копию этой строки ... –

+0

Да, я бы ожидал этого. Я бы посоветовал создать собственный объект stringbuf и привязать к нему поток. –

+0

Если вы хотите использовать буфер для использования ostrstream not ostringstream – Mark

1

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

+0

Этот учебник был полезен для реализации пользовательского std :: streambuf http://www.mr-edd.co .uk/блог/beginners_guide_streambuf –

Смежные вопросы