做者:冯老师,华清远见教育集团讲师。程序员
在面试题中常常考到各类各类的字符串处理函数,下面就一个简单的字符串长度处理函数作讲解并演示如何编写一个高效的strlen函数。面试
#include <stdio.h>
#define OPTIMIZE 1
#if OPTIMIZE
/*如下代码段是针对32位CPU深度优化调整后的strlen函数,咱们充分利用CPU的数据宽度,使用int指针去访问内存数据,每次按照CPU字长去读取数据,极大地利用了CPU访问内存的能力。虽然每次读取一个int型都须要判断其中是否出现空数据字节(‘\0’),可是依然要比按字节访问内存提升极大的运行速度。 */
int mystrlen(char *str)
{
/* 为了不数据指针的自增致使频繁访问内存,全部的临时变量都声明为寄存器存储类型,以提升运行速度 */
register int *tail = (int *)str;
register int value;
register int len = 0;
char *p;
while (1) {
/* 用临时变量接受读取的内存值,目的是避免在接下来的判断表达式中使用*tail以提升运算速度(*tail会让编译器生成一条访存指令,拖慢速度) */
value = *tail;
/* 用if运算来判断每个字节,以确保若是遇到空字节(‘\0’)则当即结束循环,不然认为没有遇到字符串结尾,则将长度计数器增长4 */
if (!(value & 0xff000000) || !(value & 0xff0000)
|| !(value & 0xff00) || !(value & 0xff))
break;
len += 4; /* 长度计数器自增4字节 */
tail++; /* 当前数据指针后移 */
}
p = (char *)tail;
while (*p++ != '\0')
len ++;
return len;
}
#else
/* 如下程序片断是简单的字符串长度计算功能,大部分程序员都会使用这种方法,缘由是简单易于编写和维护。可是其运行的效率实在不敢恭维,由于其使用了一个char型指针去访问内存,每次读取一个字节,严重浪费了32位CPU的数据宽度。 */
int mystrlen(char *str)
{
char *tail = str;
while ('\0' != *tail)
tail++;
return tail - str;
}
#endif
/* 如下主程序用来测试编写的函数速度,方法是用编写的函数计算长度为50个字符的字符串一千万次,并用time函数计算运行总时间。 */
int main()
{
char *str = "12345678901234567890123456789012345678901234567890";
int len;
int i;
for (i = 0; i < 10000000; i++)
len = mystrlen(str);
return 0;
}函数
如下是测试结果:测试
没有优化后的测试结果:优化
优化后的测试结果:3d