一、简介
看到标题,大家也许知道我们要讲的内容是什么了。但是很多人可能又对这个达夫设备(Duff's Device)感到很陌生,这到底是什么东东啊?所谓的Duff's Device其实只是一种代码的特殊写法,他将switch和do...while结合起来使得算法效率变高,先上代码:
void fDuffDevice( int * to, int * from, int count)
{
int n = (count + 7 ) / 8 ;
switch (count % 8 )
{
case 0 : do { * to ++ = * from ++ ;
case 7 : * to ++ = * from ++ ;
case 6 : * to ++ = * from ++ ;
case 5 : * to ++ = * from ++ ;
case 4 : * to ++ = * from ++ ;
case 3 : * to ++ = * from ++ ;
case 2 : * to ++ = * from ++ ;
case 1 : * to ++ = * from ++ ;
} while ( -- n > 0 );
}
}
可能初看,会觉得这个代码很奇怪,能否编译通过呢?亲自测试了一下,能够正常编译。
二、代码分析
我们写了一段测试代码,具体如下:
#include <stdio.h>
void fDuffDevice( int * to, int * from, int count)
{
int n = (count + 7 ) / 8 ;
switch (count % 8 )
{
case 0 : do { * to ++ = * from ++ ;printf("case 0 :Running\n");
case 7 : * to ++ = * from ++ ;printf("case 7 :Running\n");
case 6 : * to ++ = * from ++ ;printf("case 6 :Running\n");
case 5 : * to ++ = * from ++ ;printf("case 5 :Running\n");
case 4 : * to ++ = * from ++ ;printf("case 4 :Running\n");
case 3 : * to ++ = * from ++ ;printf("case 3 :Running\n");
case 2 : * to ++ = * from ++ ;printf("case 2 :Running\n");
case 1 : * to ++ = * from ++ ;printf("case 1 :Running\n");
} while ( -- n > 0 );
}
}
int main()
{
int i = 0;
int to[20] = {0};
int from[20] = {0};
for(i = 0 ;i < 20 ;i++)
from[i] = i;
fDuffDevice(to,from,20);
for(i = 0 ;i < 20 ;i++)
printf("to[%d] = %d;\n", i ,to[i]);
return 0;
}
以下是打印出来的效果:(具体的运行顺序不用我再讲了吧!)
case 4 :Running
case 3 :Running
case 2 :Running
case 1 :Running
case 0 :Running
case 7 :Running
case 6 :Running
case 5 :Running
case 4 :Running
case 3 :Running
case 2 :Running
case 1 :Running
case 0 :Running
case 7 :Running
case 6 :Running
case 5 :Running
case 4 :Running
case 3 :Running
case 2 :Running
case 1 :Running
to[0] = 0;
to[1] = 1;
to[2] = 2;
to[3] = 3;
to[4] = 4;
to[5] = 5;
to[6] = 6;
to[7] = 7;
to[8] = 8;
to[9] = 9;
to[10] = 10;
to[11] = 11;
to[12] = 12;
to[13] = 13;
to[14] = 14;
to[15] = 15;
to[16] = 16;
to[17] = 17;
to[18] = 18;
to[19] = 19;
三、意义
我们一般使用用for循环
或者while循环
的时候,如果执行循环内容本身用不了多少时间,本质上时间主要是消耗在了每次循环的比较语句上边。而事实上,比较语句是有很大优化空间的,我们假设你要循环10000次,结果你从第一次开始就不断的比较是否达到上界值,这是不是很徒劳呢?而达夫设备(Duff's Device)可以大大减少这种比较,我们可以看到,上面的代码,8次才进行一次比较。这样就大大节约了时间。提高了效率。
四、写在最后的话
这种写法不是很值得我们借鉴。毕竟这不是符合我们“正常”逻辑的代码,至少C/C++标准不会保证这样的代码一定不会出错。另外, 这种代码冷知识,估计有很多人根本都没见过,如果自己写的代码别人看不懂,估计会被骂的。虽然我觉得达夫设备是个很高效、很值得我们去学习的东西。把一次消耗相对比较高的操作“分摊“到了多次消耗相对比较低的操作上面,就像vector中实现可变长度的数组的思想那样,节省了大量的机器资源,也大大提高了程序的效率。