想提高vb效率的时候,常用测试来检验算法的优劣,但测试本身的“算法”却被忽略!这里我很想说一段“故事”:
我在研究一个alpha运算的代码时,就感到了同样的问题:他把vb算法与api中的alphablend做了比较,结果证明vb更快。因为我也写过一个alpha运算的代码,所以针对他的源码做了分析,发现二者有两个不同,
一是他使用的是了dib,而我的是基于ddb,所以他的速度很一致,而我的因涉及不同色深算法不同,自然速度也不一样,16位色处理始终慢些;
二是他使用了safearray结构指针,而我没有,我无法用这种指针的一个原因是,他的dib位图是预先载入自己创建的dibsection的,创建时便已获取了数据指针,这样就会比ddb少了一步数组复制过程。
指针并不是vb的独门绝技,难道,用了指针就会比c快?再看了一下那段代码用的测试方法,我才明白:dib是预先载入的,计时的只是一个运算部分,alphablend当然没有这个优先权,它虽然也是用这个dib,但它没有其指针,它仍需先获取这个dib数据,再处理,最后再输出回这个dib,再由vb统一输出到屏幕,这当然慢。
其实用dib处理的确简单,因为可以统一位图数据格式,一个算法便能适应所有色深。但我为什么后来没用dib,原因就是一点:dib慢呀,alpha效果是一种屏幕动态效果,原始图都是基于ddb的,所以实际应用中是不会有现成的dib可用的。
若使用dib,必需得有一次转换,将ddb绘入新创建的dibsection,别小看了这一次转换,我测试表明,用这种方式进行一次完整的alpha处理,ddb绘入dibsection的时间占整个处理时间的70%!!!
另一个让我大为吃惊的是,单独对运算部分计时,我发现用指针的算法,与我不用指针直接处理数组速度几乎一样。所以当把“从ddb做输入源,到重新输出回ddb”做为一个过程来看待时,我的ddb处理法比dib法快了3倍多,但仍远慢于alphablend,我对vb的指针用法更开始茫然。
所以各种测试一定不要离开实际应用这个范围,不然真会走入歧途。bluedog() 的几个函数,除那个汇编外,与我在处理中使用的方法都一样,但我是内置于处理过程中的,不用说肯定比函数调用要快;汇编那段估计是调用一个利用c做移位运算的函数,就象我对copymemory速度都感到失望一样,做为一次函数调用,我对其速度也不敢抱太多幻想。
根据我反复测试的结果,我一直想推出一个让很多人大跌眼镜的结论:copymemory有时还没有用循环从数组直接取值快!
以前认为它快的结论是源于对测试条件的误解,在我们测试时,换有不同算法总是在调试环境下先进行比较的,在调试环境下用copymemory代替用循环从数组取值,会使速度明显提高,为什么?因为copymemory是已经过编译的函数!若循环也经过本机码编译,其就会比调用函数copymemory快了。因为它在同等执行方式下,省去了函数调用的开销。
不过copymemory在数据增大时速度下降不明显,而循环这方面就弱了,所以大数据还是建议用copymemory的,这个长度不好确定,由测试情况决定,一般32字节以上,还是值得调用一下函数的。