算法加速小伎俩<一>

作者在 2009-06-11 00:58:43 发布以下内容
一、从O(g(n))到O(1)
    例:输入字节x,输出x的置换(比特位恰好相反),函数名reverse_bit8。
    这个算法很多地方都需要用到。你很快就可以找到很多高效的算法实现它。
    比如1:通过逐位测试,按测试结果对结果进行或、移位运算。算法如下:
    unsigned char y = 0;
    for(int i = 0;i < 8;i++)
    {
        y = y << 1;
        if(x & 0x01)//对最低位进行测试
           y = y | 0x01;
        x = x >> 1;
    }
    如果写得高深一点:
    unsigned char y = 0;
    signed char xx = x;//使用有符号字节类型
    for(int i = 0;i < 8;i++)
    {
        y = y >> 1;
        if(xx < 0)//对最高位进行测试
           y = y | 0x80;
        xx = xx << 1;
    }
    效率差不多,不知道还有没有比这效率更高的算法了。
    很多情况,这个函数需要重复高频调用,所以可以考虑另一种常用方法:查表法。
    很简单,所有情况共256种,表的规模不算很大,而且表元素的值就可以通过上面的算法计算出来。最终的reverse_bit8就成了这样:
    unsigned char reverse_bit8(unsigned char x)
    {
        return some_namespace_or_class::pTable[x];
    }
    另外,当需要使用reverse_bit8之前,需要把这张表准备好。很多人一定想到使用文本文件形式保存这张表,但有更好的方法:保存为二进制文件。这样就不需要通过类型转换将文本中的值读入内存了。当需要读取表的时候,只需要:
    FILE* pInFile = fopen("table.dat","rb");
    fread(pTable,sizeof(unsigned char),256,pInFile);
    如此一来,程序整体效率就提升了很多了。
    当然,如果是在windows下,还可以使用文件映射机制,或者使用动态链接库,来快速、方便地初始化甚至直接使用表,可以参看《windows核心编程》。
编程杂记 | 阅读 3003 次
文章评论,共3条
vfdff
2009-06-15 13:00
1
文件读写不是很慢吗?
夜风依旧(作者)
2009-06-15 22:18
2
<div class="quote"><span class="q"><b>vfdff</b>: 文件读写不是很慢吗?</span></div>文件只用另一个程序需生成一次,以后都可以让主程序随时使用,另外,读数据只在主程序启动时读入内存,256字节,且只读一次,而这个时候计算密集的一段程序还没有开始,以后就直接访问内存取出结果。毋庸置疑,效率是很高的啊,而且计算次数越多,效率越高啊。
夜风依旧(作者)
2009-06-15 22:29
3
<div class="quote"><span class="q"><b>vfdff</b>: 文件读写不是很慢吗?</span></div>而且如果是像这个例子一样数据量比较小而且数据都不用跟新的话,干脆做成数组,直接放到内存里。不过有的时候,数据需要适时跟新,就不好办了。
游客请输入验证码