算法说明
将原始位图点阵分割成8*8的小块,则该小块各种组合值恰好可以使用64位完全表示,即横向8个点可以使用一个字节表示,纵向8行则即8字节。
- 对于逆时针旋转90°,源点阵第一行旋转后(一个字节),对应目标点阵的第一列(8个字节的第一位同时赋值),参见下图
- 由此可以得出,对于每一行(1字节)都可以有一个64位的整型与之一一对应,对于不同行的点阵数据,只要在目标点阵数据做移位操作,就可以得到相应的翻转效果。
- 逆时针旋转的表占用空间大小为:8 * 2^8 = 4096字节,同理顺时针旋转的表占用空间的大小为4096字节
对于32位的CPU似乎直接使用64位的整型的话应该也是要拆分两次计算吧(个人猜测)。这里果断将原来的8*8点阵,拆分为两个4*8点阵(横向4点,纵向8点, 32位),分两次计算,将最后得到的值分别拼接到目标的8*8点阵中。
逆时针旋转90°效果如下图
- 每次取出源点阵的一行,分别取出高4位与低4位,再将高低4位分别查找32位映射表,最后的值再拼接至目标点阵
- 拆分后逆时针旋转的表占用空间大小为:4* 2^4 = 64字节,同理顺时针旋转的表占用空间的大小为64字节
查表法比普通的直接位操作理论上有8倍左右的差距
源码:https://git.oschina.net/ccyuan/RotateBitmap90.git
算法测试
测试环境
- 操作系统: win7 64位
- 编译器:TDM-GCC 4.9.2 32-bit
- IDE:Dev-C++ 5.11
- 点阵位图存储方式LSB-MSB(即点阵的最左上角的点存储在第一个字节的第一位,区分单色图,单色图为存储在一个字节的第八位)
测试内容
- 对于同一源点阵,统计使用位操作法与查表法翻转源点阵所需要的时间
- 源点阵大小由12*24递增至640*640,递增单位4点
- 源点阵内容:全白图,随机图(使用c标准库的rand生成的数据),全黑图
测试结果
取位操作法花费时间与查表法花费的时间比值。
预计结果
|
|
位操作时间/查表时间 |
备注 |
| 全白图 |
< 1 |
空白字节不做操作,因此时间要比查表时间短 |
| 随机图 |
4~8 |
存在空白字节,因此时间<8 |
| 全黑图 |
8左右 |
每位都需要进行操作,因此时间最长 |
实际结果
全程数据读取
|
|
位操作时间/查表时间 |
备注 |
| 全白图 |
0.37~0.55 |
这时间比,不科学呀 |
| 随机图 |
5.6~8.2 |
符合预期 |
| 全黑图 |
3.3~3.6 |
完全不科学呀 |
小点阵64*64以内
|
|
位操作时间/查表时间 |
备注 |
| 全白图 |
0.5~0.65 |
|
| 随机图 |
2.6~3.5 |
符合预期, |
| 全黑图 |
2.6~3.4 |
完全不科学呀 |
统计结果对比图
整个流程数据统计
局部放大图
小点阵
参考资料
c/c++在windows下获取时间和计算时间差的几种方法总结
转载于:https://my.oschina.net/ccyuan/blog/738901