反复拨打电话时
的printf /的snprintf / fprintf中/等。
使用相同的格式字符串,并且在每次调用参数位置时重新分析格式字符串没有意义。
是否有人知道一个库提供了预先解析格式字符串然后将其传递给printf样式函数的功能,从而减少了处理时间?
答案 0 :(得分:2)
大多数stockf函数都相当有效,格式字符串是单个连贯的源,而不是由iostreams和Boot.Format生成的大量短缓冲区,在大多数情况下它(格式字符串)是大量的您将要复制到目标缓冲区的内容。 “解析”printf格式相当便宜,但如果您确实已经验证了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;
}
答案 1 :(得分:0)
Boost.Format解析格式字符串以创建格式化程序对象一次,然后可以重复使用。虽然解析是缓存的,但看起来你会得到多个中间字符串副本,所以我怀疑它会更快。
您可以通过printf
实现来缓存解析阶段。这似乎可能产生重大节约的唯一情况是:
从根本上说,printf
字符串的设计解析起来非常便宜,并且不清楚许多中间格式会更好。