今天才看到循环可以这样使用,真时大开眼界,太强了。
先看一个例子,打印a个*:
int a = some_number ;
int n = ( a + 4 ) / 5 ;
switch ( a % 5 )
{
case 0: do
{
putchar ( '*' ) ;
case 4: putchar ( '*' ) ;
case 3: putchar ( '*' ) ;
case 2: putchar ( '*' ) ;
case 1: putchar ( '*' ) ;
} while ( --n ) ;
}
printf ( "\n" ) ;
以前对于循环N次只是如下这样做:
for(i=0;i<N;i++)或while(N--){...}或do{...}while(N--);
读过
C编程规范,知道:
1.如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面,以减少判段次数,尤其是N比较大的情况.
2.在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU 跨切循环层的次数。
而Duff Device技巧的基本思想是--减少循环测试的执行次数
如果在一个for循环中,其中操作执行得如果足够快(比如说,一个赋值)——那么测试循环条件占用了循环所用时间的很大部分。循环应该被部分解开,这样数
个操作一次完成,测试操作也做的较少。其实,是通过switch语句将要进行的连续循环操作的次数进行了预判(根据擦case语句的位置)然后依次执行,
而不必每次都去进行测试条件。在这里Duff's Device是个新颖的,有创造力的解决方案。
对于例子中,如果打印1000000个*,这个可以减少循环次数1000000-->200000
Duff's Device对效率的负面影响可能来自于代码膨胀(一些处理器更善于处理紧凑的循环而不是大的循环)和特别的结构。优化器被做成当遇一些更加技巧性的结构时可能会不知所措从而生成比较保守的代码。
看另外一个例子:
/*Example1:
1 #define ARRAY_SIZE 1000000
2 int n = ARRAY_SIZE 1000000 ;
3 int n4 = n >> 2;
4 int i = 0;
5
6 int a[ARRAY_SIZE 1000000];
7
8 for (i = 0; i <
n ;i += 4) {
9 a[i] = i;
10 a[i+1] = i+1;
11 a[i+2] = i+2;
12 a[i+3] = i+3;
13 }
14 time for Example1(未优化编译!):
real 0m0.004s user 0m0.001s
sys 0m0.004s
15 Example2:
16 for (i = 0;i < ARRAY_SIZE 1000000;i++) {
17 a[i] = i;
18 }
time for Example2(未优化编译!):
real 0m0.014suser 0m0.004s
sys 0m0.009s
加-O2后两者均为:
real 0m0.001suser 0m0.000s
sys 0m0.002s
Reference:http://blogs.sun.com/weixue/entry/duff_s_device_%E8%BE%BE%E5%A4%AB%E8%AE%BE%E5%A4%87
http://likunarmstrong.blogchina.com/2825625.html
阅读(1257) | 评论(0) | 转发(0) |