Я пишу встроенное приложение. В некоторых местах я использую станд.:: ostringstream много, так как это очень удобно в моих целях. Однако я просто обнаружил, что хит производительности является экстремальным значением начиная с добавляющих данных к потоковым результатам в большом количестве вызовов к malloc и свободный. Там какой-либо путь состоит в том, чтобы избежать его?
Моя первая мысль делала ostringstream помехи и сбрасывала их с помощью ostringstream:: набор (""). Однако это не может быть сделано, поскольку мне нужны функции, чтобы быть повторно используемым.
Ну, решением Booger будет переход на sprintf()
. Это небезопасно и чревато ошибками, но зачастую быстрее.
Однако не всегда. Мы не можем использовать его (или ostringstream) в моей работе в реальном времени после инициализации, потому что оба выполняют выделение и деаллокацию памяти.
Наш способ обойти эту проблему заключается в том, что мы проделываем много ходов, чтобы убедиться, что мы выполняем все преобразования строк при запуске (когда нам еще не нужно работать в реальном времени). Я думаю, что была одна ситуация, когда мы написали наш собственный конвертер в массив фиксированного размера, выделенный из стека. У нас есть некоторые ограничения на размер, на который мы можем рассчитывать для конкретных преобразований, о которых идет речь.
Для более общего решения вы можете рассмотреть возможность написания собственной версии ostringstream, которая использует буфер фиксированного размера (с проверкой на ошибки, разумеется, при сохранении границ). Это будет небольшая работа, но если у вас много таких потоковых операций, это может стоить того.
Вероятно, одобренным способом решения этой проблемы было бы создание собственного объекта basic_stringbuf
для использования с вашим ostringstream
]. Для этого у вас есть несколько вариантов. Один из них - использовать буфер фиксированного размера, и overflow
просто не сработает, когда / если вы попытаетесь создать слишком длинный вывод. Другая возможность - использовать вектор в качестве буфера. В отличие от std :: string, vector гарантирует, что добавляемые данные будут иметь амортизированную постоянную сложность. Он также никогда не освобождает данные из буфера, если вы не заставляете это делать, поэтому обычно он увеличивается до максимального размера, с которым вы имеете дело. С этого момента он не должен выделять или освобождать память, если вы не создаете строку, длина которой превышает доступную в настоящее время длину.
Если вы знаете размер данных до создания потока, вы можете использовать ostrstream, конструктор которого может принимать буфер в качестве параметра. Таким образом, не будет управления памятью данных.
std :: ostringsteam
- удобный интерфейс. Он связывает std :: string
с std :: ostream
, предоставляя пользовательский std :: streambuf
. Вы можете реализовать свой собственный std :: streambuf. Это позволяет вам полностью управлять памятью. Вы по-прежнему получаете хорошее форматирование std :: ostream
, но у вас есть полный контроль над управлением памятью. Конечно, в результате вы получаете форматированный вывод в виде char []
- но, вероятно, это не проблема, если вы разработчик встраиваемых систем.