snprintf和strncat的执行速度如何比较?

时间:2011-08-23 00:05:51

标签: c string

我有一个程序在缓冲区中连接一些字符串。

之前我正在使用strncpy。在使用snprintf而不是strncat查看web上的一些建议后,我切换到了snprintf。但是,我注意到之前执行此部分程序(字符串连接)的延迟。这可能,snprintf可以减慢程序的执行速度吗?如果没有,那么我会在我的程序中寻找其他一些因素。

if(iOffset<MAX_BUFF_SIZE && iOffset>0)
{
  ....... 
  iOffset += snprintf(cBuff+iOffset, sizeof(cBuff)-iOffset, "%s", "String1");
  ...... 
}

我重复上面的代码片段12次,以便将字符串附加到cBuff。

编辑:每1秒后重复12次。

6 个答案:

答案 0 :(得分:4)

有一些想法可以想到:

  • 不要过早优化您的计划
  • 当你准备好进行优化时,使用像分析器这样的工具来发现真正的慢下来的地方

如果您不熟悉性能分析,或者非常渴望了解时间详细信息,则可以始终在代码周围包含计时器。请参阅gettimeofday()或clock()的参考资料以及有关这些代码的相应警告。基本上你可以在执行之前获得时间,之后的时间并比较它们。注释掉你的代码行并输入旧代码并计时。

尽管如此......这是探查器为您做的事情的一部分。找出“为什么”某些东西很慢的东西有时很复杂,因为可能还有其他考虑因素(即在硬件层面)你不知道。

与程序的总执行时间相比,执行12次函数可能是微不足道的。

答案 1 :(得分:4)

strncat遇到Schlemiel the Painter问题。你使用snprintf的方式不然(虽然也可以这样使用strncat,并以这种方式回避问题。)

答案 2 :(得分:1)

假设您考虑到Chris Jester-Young提到的问题,通过考虑“Schlemiel the Painter”问题,您很可能会发现strncat()的头对头比较比你snprintf()更快 - 就像你使用它一样。

snprintf()确实有(虽然很小,在这种情况下)必须解析strncat()没有的格式字符串的开销。

您提供的代码段与the linked question中给出的示例不同,可能会更改比较。

斯蒂芬提到,对于大多数运行strncpy() 12次而非snprintf()的平台,应该产生微不足道的差异。在这里使用分析器非常有用,可以确保您专注于正确的区域。


在您提供的示例中,您尝试将const字符串附加到缓冲区。如果您正在使用真实代码(而不仅仅是一个简单的示例),并且字符串复制确实是一个重要的执行时间区域,您可能能够优化该区域。

一种常见的优化方法是找到可以在编译时预先计算的计算,而不是在执行时。 如果您只对处理const字符串感兴趣,您可以有效地预先计算字符串的长度,然后使用memcpy()而不是strncpy()来执行字符串追加。 memcpy()通常针对您的平台进行了优化。

当然,这样的解决方案将以牺牲缓冲区溢出和指针算法为代价。

答案 3 :(得分:1)

复制“重复连接”习惯并仅使用snprintf来执行此操作并非真正遵循建议以避免strcat。你应该做的事情如下:

snprintf(buf, sizeof buf, "%s%s%s%s", str1, str2, str3, str4);

这比重复调用snprintf快得多,这会给每次调用带来很多开销,实际上它会正确地使用这个习惯用法。

答案 4 :(得分:0)

我不是探查者,所以我不能肯定说什么是慢的。

正如@chris所提到的,strncat可以做多次工作而不是一遍又一遍地找到目标字符串的结尾。您可能已经能够缓解这种情况,因为它似乎正在跟踪消耗的空间,因此您可以在每次后续调用时从最后开始。

另一方面,与strcat或strcpy相比,snprintf可能需要做额外的工作,因为它必须在每次调用时解析“%s”以找出如何处理变量参数列表。

strncat运行得更快,我并不感到惊讶,特别是在缺乏激进的优化级别的情况下。

答案 5 :(得分:0)

那些提到在你注意到减速后不提早优化的人是愚蠢的。在这种情况下,您甚至不需要运行探查器。你已经有经验证据转向snprintf减慢了你的计划。

我在金融行业工作,业绩是关键,几乎总是喜欢sprintf到snprintf。可以在一个受控制的环境中编写快速稳定的应用程序。