在循环条件中使用strlen()比检查null字符更慢吗?

dat*_*ili 14 c string-length strlen

我已经读过使用strlen比这样的测试更昂贵:

我们有一个x100个字符的字符串.

我觉得

for (int i = 0; i < strlen(x); i++)
Run Code Online (Sandbox Code Playgroud)

比这段代码贵:

for (int i = 0; x[i] != '\0'; i++)
Run Code Online (Sandbox Code Playgroud)

这是真的吗?也许第二个代码在某些情况下不起作用,所以最好使用第一个代码吗?

下面会更好吗?

for (char *tempptr = x; *tempptr != '\0'; tempptr++)
Run Code Online (Sandbox Code Playgroud)

Mat*_*ewD 27

for (int i=0;i<strlen(x);i++)
Run Code Online (Sandbox Code Playgroud)

此代码调用strlen(x)每次迭代.因此,如果x长度为100,strlen(x)将被调用100次.这非常昂贵.此外,每次都以与for循环相同的方式strlen(x)迭代x.这使得O(n ^ 2)复杂度.

for (int i=0;x[i]!='\0';i++)
Run Code Online (Sandbox Code Playgroud)

此代码不调用任何函数,因此比前一个示例快得多.由于它仅循环遍历循环一次,因此它是O(n)复杂度.

  • 大多数编译器(包括gcc)都足够智能来缓存strlen的结果,因此两个循环的性能几乎相同. (4认同)
  • @Paul R:第二个仍然会更快,因为strlen迭代一次,然后OP在他的循环中再次迭代,而在第二个循环中只有一次迭代.然而,就事物的规模而言,这是一个非常微观的优化. (2认同)
  • @PaulR 你确定 GCC 在所有情况下都会这样做吗?它没有任何方法知道使用多个线程和全局字符串时会发生什么;另一个线程可以在循环时修改字符串。或者,如果您使用全局字符串,它可能不会进行优化。 (2认同)

Art*_*yom 11

第一个代码在i的每次迭代中检查x的长度,并且需要O(n)来找到最后的0,所以它需要O(n ^ 2),第二种情况是O(n)


Ash*_*nko 5

是的,你的第二个可能无法 100% 地工作,但它会稍微安静一些。这是因为使用 strlen() 时,每次都必须调用该方法。更好的方法就像这样

int strLength = strlen(x);
for (int i = 0; i < strLength; i++)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。