0. 前言
其实基本都没什么机会做这么一个基础的优化,一般基础库里就有函数可以直接拿来用。
这里以snprintf为基准,给大家展示一下每一个优化带来的些许收益。
1. 优化过程
1.最初使用的是snprintf
2.除10和模10, buf就地reverse
由于每次模10之后产生的都是个位数,所以buf中的字符是逆序的,需要在最后对字符数组做一次reverse。
3.将除10改成乘法加移位
这时除10对应的操作是x * 0x66666667 >> 34;
在小于0x27ffffff0时使用乘法加移位,大于0x27ffffffb时直接除10,目的是避免溢出。
4.在上面的基础上优化成除100,加一个查表
表里存放00到99的字符,在余数小于100时就查表获得对应的字符,这里将步长加大为两倍可以减少一半的循环。
5.将除100优化成两次除10(乘法加移位)
优化之后除100这个操作变得更快。
6.计算出整数换算成10进制时的长度,规避后面的reverse操作。
计算出长度的函数使用了类似二分查找的方式,快速确定位数,会增加一定的开销。字符串较短的情况下,可能反而性能会更差一些;在字符串长度较长时,考虑到就地reverse可能也会消耗较多的时间,这里可能会获得一些收益。
7.用一次除法将大于12位的整数拆分成高位和低位两个数。
大于0x27ffffff0的数字要除100。
通过一次除法拆分成两个小于0x27ffffff0的数减少做除法的次数。
执行100000000次的CPU时间对比
在服务器上跑出来的结果