Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top