C库中strlen的源码实现

简单介绍了strlen的改进实现和系统库的实现。

我们知道,strlen函数是C标准库中获取字符串长度的api。我们在C语言刚入门时,往往会被要求实现strlen函数。于是,我们信心满满的写下下面的代码:

size_t strlen(const char *str) {
    if (str == NULL)
        return 0;
    size_t length = 0;
    while(str[length] != 0)
        length++;
    return length;
}

进阶一点,还可以改进下:

size_t strlen(const char *str) {
    if (str == NULL)
        return 0;
    const char *cp = str;
    while (*cp++)
          ;
   return (cp - str - 1);
}

上面的方法在执行结果上都没有问题,但毋庸置疑的是,系统中libc的实现绝对不会如此简单。

strlen的改进

参考:

https://code.woboq.org/userspace/glibc/string/strlen.c.html

目的是通过减少数据从内存存取到寄存器的次数,手段就是先字节对齐,然后每次读取一个4/8字节的多字节数据,对多字节数据遍历是否存在\0。

strlen的终极实现

如果你用改进后的代码替换掉系统的strlen,还是会发现执行耗时大约是系统strlen的4,5倍的样子,那么系统的strlen是如何实现的呢?

直接上代码吧:

iOS xnu strlen的实现:

https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/arm64/strnlen.s.auto.html

Android strlen的实现:

http://androidxref.com/9.0.0_r3/xref/bionic/libc/arch-arm64/generic/bionic/strlen.S

全部都是汇编实现!!