【发布时间】:2015-12-01 19:59:37
【问题描述】:
我找到了这段代码
int strlen_my(const char *s)
{
int len = 0;
for(;;)
{
unsigned x = *(unsigned*)s;
if((x & 0xFF) == 0) return len;
if((x & 0xFF00) == 0) return len + 1;
if((x & 0xFF0000) == 0) return len + 2;
if((x & 0xFF000000) == 0) return len + 3;
s += 4, len += 4;
}
}
我很想知道它是如何工作的。 ¿ 谁能解释一下它是如何工作的?
【问题讨论】:
-
它用未定义的行为换取了一个非常可疑的加速(它很可能甚至更慢)。并且不符合标准,因为它返回
int而不是size_t -
@MillieSmith:这是最小的问题,因为大多数 64 位系统都是 I32LP64 (POSIX)。问题是访问不对齐,字节序(如您所说)。即使平台上允许未对齐的访问,它们也可能比对齐的访问慢得多。更不用说多重掩码和条件操作了。
-
if((x & 0xFF) == 0)--> 依赖字节序 -
这可能来自here,它确实提到了与此代码的许多权衡,尽管它没有提到它是未定义的行为。链接代码的来源通常很有帮助。
-
值得注意的是,glibc 使用了一个漂亮的 bithack,它可以一次测试四个或八个字节(取决于 long 的大小),使用单个条件来检查是否没有字节为 0。 (sourceware.org/git/?p=glibc.git;a=blob;f=string/…) 在特定架构上,它可以使用 SSE(或等效)或其他 bithacks 做得更好。道德:使用标准库。
标签: c bitwise-operators strlen