При повторном вызове
Printf/snprintf/fprintf/и т.д..
с той же строкой формата, и на самом деле не имеет смысла переписывать строку формата для каждого вызова для позиций аргументов.
Кто-нибудь знает о библиотеке, которая обеспечивает функцию синтаксического анализа строки формата спереди, а затем передает ее функции printf-стиля, тем самым сокращая время обработки?
Большинство функций printf являются достаточно эффективными, строка формата представляет собой единый, когерентный источник, а не обильные короткие буферы, созданные iostreams и Boot.Format, и в большинстве случаев это (строка формата) является основной частью того, что вы собираются скопировать в буфер назначения. Форматы печатных форматов "Parsing" довольно дешевы, но если вы действительно подтвердили, что ваша функция printf является узким местом и что это не результат плохого управления буферами printf, вы также должны знать, какие форматы дороги.
Часто printf/snprintf будет отображаться в профилях с выборкой, потому что это неизбежно связано с достаточной передачей
snprintf(thatBuffer, someSize, "[%u/%u/%u %u:%u:%u.%llu %s:%u] %p %s %f",
/* a 2-cacheline date object */ date->dy, date->mo, date->yr, date->hr, date->mi, date->sec, date->ms,
__FUNCTION__, __LINE__, // why didn't you embed those in the format?
object->ptr, // another cache line
message, // string from somewhere on the heap, page fault,
floaty // floats and doubles are usually expensive
);
и мы даже не использовали причудливое форматирование.
Существует несколько способов оптимизации печати:
Например, в GCC 4.8.2, Clang 3.5 и MSVC 2013, следующее:
template<typename... Args>
int formatText(const char* const fmt, Args&&...)
{
int len = std::min(snprintf(m_text, m_textSize, fmt, std::forward<Args>(args)...), m_textSize);
m_text[len] = '\0';
return len;
}
сравним в 3 раза быстрее, чем следующее:
int inline formatText(const char* const fmt, ...)
{
va_list args;
va_start(args, fmt);
int len = std::min(vsnprintf(m_text, m_textSize, fmt, args), m_textSize);
va_end(args);
m_text[len] = '\0'; // assume m_textSize is storage size - sizeof('\0')
return len;
}
Boost.Format анализирует строку формата для создания объекта форматирования, один раз, который затем можно повторно использовать. Хотя синтаксический анализ кэшируется, похоже, что вы получаете несколько промежуточных копий строк, поэтому я сомневаюсь, что это будет быстрее.
Вы можете printf
реализацию printf
для кэширования этапа синтаксического анализа. Единственными ситуациями, когда это, похоже, может привести к значительной экономии, являются:
По сути, строки printf
разработаны, чтобы быть довольно дешевыми для синтаксического анализа, и неясно, что многие промежуточные форматы будут лучше.
printf
как на самое большое узкое место в вашем коде?