整数转化为字符串的函数相信大家在做一些算法题的时候就已经做过,一般能想到的代码如下:
1 size_t my_uint32_to_str(uint32_t value, char *dst) 2 { 3 size_t length = digits10(value); 4 size_t len = length; 5 while(value) 6 { 7 dst[length - 1] = '0' + (value % 10); 8 length--; 9 value /= 10; 10 } 11 return len; 12 }
这是最简单不过的转化函数了,这个转化函数代码很少,而且简单易懂。效率也不错,但是下面这个功能相同的函数,效率更是搞得惊人,比上面跟这个函数快了将近 30%,代码如下:
1 size_t facebook_uint32_to_str(uint32_t value, char *dst) 2 { 3 static const char digits[201] = 4 "0001020304050607080910111213141516171819" 5 "2021222324252627282930313233343536373839" 6 "4041424344454647484950515253545556575859" 7 "6061626364656667686970717273747576777879" 8 "8081828384858687888990919293949596979899"; 9 size_t const length = digits10(value); 10 size_t next = length - 1; 11 while (value >= 100) { 12 const int i = (value % 100) * 2; 13 value /= 100; 14 dst[next] = digits[i + 1]; 15 dst[next - 1] = digits[i]; 16 next -= 2; 17 } 18 // Handle last 1-2 digits 19 if (value < 10) { 20 dst[next] = '0' + uint32_t(value); 21 } else { 22 const int i = uint32_t(value) * 2; 23 dst[next] = digits[i + 1]; 24 dst[next - 1] = digits[i]; 25 } 26 return length; 27 }
这两个函数都调用了 digists10() 函数,该函数用来统计一个十进制数的位数。所以这块的影响可以忽略,digists10() 函数代码如下(我自己写的,效率可能不是最好的):
1 size_t digits10(uint32_t value) 2 { 3 int length = 0; 4 while(value) 5 { 6 length++; 7 value /= 10; 8 } 9 return length; 10 }
现在我们对比一下这两个函数的执行效率,先贴出我的测试代码:
1 #define MAX 1000000 2 int main() 3 { 4 clock_t begin, duration; 5 int digit = 1, len = 0; 6 char dst[6],dst2[6]; 7 begin = clock(); 8 for(int i= 0; i < MAX; i++) 9 { 10 len = my_uint32_to_str(digit,dst); 11 dst[len] = '\0'; 12 } 13 duration = clock() - begin; 14 printf( "函数 my_uint32_to_str 的运行时间大约为:%dms\n", duration*1000/CLOCKS_PER_SEC ); 15 //printf("%s",dst); 16 begin = clock(); 17 for(int i= 0; i < MAX; i++) 18 { 19 len = facebook_uint32_to_str(digit,dst2); 20 dst2[len] = '\0'; 21 } 22 duration = clock() - begin; 23 printf( "函数 facebook_uint32_to_str 的运行时间大约为:%dms\n", duration*1000/CLOCKS_PER_SEC ); 24 return 0; 25 }
当 digists = 1 时,测试结果如下:
当 digists = 11 时测试结果如下:
当 digists = 101 时测试结果如下:
当 digists = 1001 时测试结果如下:
当 digists = 10001 时测试结果如下:
当 digists = 100001 时测试结果如下:
当 digists = 1000001 时测试结果如下:
当 digists = 10000001 时测试结果如下:
当 digists = 100000001 时测试结果如下:
当 digists = 1000000001 时测试结果如下:
从测试结果我们可以看出,效率确实提高了很多。分析原因,我觉得应该是 facebook_uint32_to_str() 函数大大缩减了 / (除)的操作。100 以内的不需要除法,而 my_uint32_to_str() 要进行 1~2 次除法;100~999,facebook_uint32_to_str() 要 1 次,my_uint32_to_str() 要 3 次;1000~9999, facebook_uint32_to_str() 要 1 次,my_uint32_to_str() 要 4 次;以此类推,facebook_uint32_to_str() 需要 digits/100 次除操作,而 my_uint32_to_str() 需要 digits 位数次除操作。
本文参考链接:http://tia.mat.br/blog/html/2014/06/23/integer_to_string_conversion.html