Существует ли способ уменьшить ostringstream malloc/free's?

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

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

8
задан Johan Kotlinski 1 March 2010 в 18:27
поделиться

4 ответа

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

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

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

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

2
ответ дан 5 December 2019 в 21:18
поделиться

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

2
ответ дан 5 December 2019 в 21:18
поделиться

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

2
ответ дан 5 December 2019 в 21:18
поделиться

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

1
ответ дан 5 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: