strncmp的实现

Bar*_*wen 3 c eglibc

为了磨练我的C技能,我下载了eglibc源代码,我遇到了strncpy.我不明白他为什么要区分n <= 4并进行4次测试的情况.

int
STRNCMP (const char *s1, const char *s2, size_t n)
{
  unsigned char c1 = '\0';
  unsigned char c2 = '\0';

  if (n >= 4)
    {
      size_t n4 = n >> 2;
      do
    {
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0' || c1 != c2)
        return c1 - c2;
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0' || c1 != c2)
        return c1 - c2;
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0' || c1 != c2)
        return c1 - c2;
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0' || c1 != c2)
        return c1 - c2;
    } while (--n4 > 0);
      n &= 3;
    }

  while (n > 0)
    {
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0' || c1 != c2)
    return c1 - c2;
      n--;
    }

  return c1 - c2;
}
Run Code Online (Sandbox Code Playgroud)

可能是它与内存布局有关,我不知道,请赐教.

ike*_*ami 6

这是一个展开的循环.以使二进制文件稍微大一点为代价,它通过消除每4个字节的3个减量,3个分支和3个条件来加速字符串比较.

通过使用与Duff设备相同的技术,甚至可以更进一步优化,但目前尚不清楚这实际上会更快.从链接页面,

这种自动处理剩余部分可能不是所有系统和编译器的最佳解决方案 - 在某些情况下,两个循环实际上可能更快(一个循环,展开,执行主副本,第二个循环处理剩余部分).问题似乎归结为编译器正确优化设备的能力; 它还可能干扰某些体系结构上的流水线和分支预测.当在4.0版本的XFree86服务器中删除了大量Duff设备实例时,性能得到了改进,可执行文件的大小明显减少.因此,在考虑使用此代码时,可能值得运行一些基准来验证它实际上是目标体系结构上目标体系结构中目标体系结构最快的代码.