标题:switch语句问题
只看楼主
卧龙孔明
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:59
帖 子:3872
专家分:684
注 册:2006-10-13
得分:0 
[bo][un]StarWing83[/un] 在 2008-7-4 08:54 的发言:[/bo]



看看这份代码,会改变你对switch的认识:
register n = (count + 7) / 8; /* count > 0 assumed */
switch (count % 8)
{
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
c ...


这段代码速率比for(i=0;i<count;i++) *to=*from++; 快吧?

My Blog: www.aiexp.info
虽然我的路是从这里开始的,但是这里不再是乐土.感谢曾经影响过,引导过,帮助过我的董凯,飞燕,leeco,starwing,Rockcarry,soft_wind等等等等.别了,BCCN.
2008-07-04 09:03
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
得分:0 
快一点儿,但主要用来体现switch的功能,这个代码叫做达夫设备(Duff’s Device)。

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-07-04 09:05
卧龙孔明
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:59
帖 子:3872
专家分:684
注 册:2006-10-13
得分:0 
[bo][un]StarWing83[/un] 在 2008-7-4 09:05 的发言:[/bo]

快一点儿,但主要用来体现switch的功能,这个代码叫做达夫设备(Duff’s Device)。

但我感觉这个速率的提高不是因为switch,而是少了计数变量的计算
例如for(i=0;i<5;i++) x++; 就慢于++x++,++x++,++x;

[[it] 本帖最后由 卧龙孔明 于 2008-7-4 09:11 编辑 [/it]]

My Blog: www.aiexp.info
虽然我的路是从这里开始的,但是这里不再是乐土.感谢曾经影响过,引导过,帮助过我的董凯,飞燕,leeco,starwing,Rockcarry,soft_wind等等等等.别了,BCCN.
2008-07-04 09:09
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
得分:0 
http://blogs.

自己看

达夫设备是一个加速循环语句的C编码技巧。其基本思想是--减少循环测试的执行次数。

如果在一个for 循环中,其中操作执行得如果足够快(比如说,一个赋值)——那么测试循环条件占用了循环所用时间的很大部分。循环应该被部分解开,这样数个操作一次完成,测试操作也做的较少。[bo]其实,是通过switch语句将要进行的连续循环操作的次数进行了预判(根据擦case语句的位置)然后依次执行,而不必每次都去进行测试条件。[/bo]
在这里Duff's Device是个新颖的,有创造力的解决方案。这里有一个使用该模型的一个实例:快速拷贝和填充。

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-07-04 09:11
卧龙孔明
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:59
帖 子:3872
专家分:684
注 册:2006-10-13
得分:0 
看了,我说的没错啊,就是减少了判断

My Blog: www.aiexp.info
虽然我的路是从这里开始的,但是这里不再是乐土.感谢曾经影响过,引导过,帮助过我的董凯,飞燕,leeco,starwing,Rockcarry,soft_wind等等等等.别了,BCCN.
2008-07-04 09:15
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
得分:0 
你后句是对的,但是前一句是“不是因为switch”,很抱歉,减少判断的功臣就是switch。

专心编程………
飞燕算法初级群:3996098
我的Blog
2008-07-04 09:16
卧龙孔明
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:59
帖 子:3872
专家分:684
注 册:2006-10-13
得分:0 
[bo][un]StarWing83[/un] 在 2008-7-4 09:16 的发言:[/bo]

你后句是对的,但是前一句是“不是因为switch”,很抱歉,减少判断的功臣就是switch。




My Blog: www.aiexp.info
虽然我的路是从这里开始的,但是这里不再是乐土.感谢曾经影响过,引导过,帮助过我的董凯,飞燕,leeco,starwing,Rockcarry,soft_wind等等等等.别了,BCCN.
2008-07-04 09:18
lingluoz
Rank: 2
来 自:苏州科技学院
等 级:新手上路
威 望:4
帖 子:749
专家分:0
注 册:2008-2-2
得分:0 
fall through哦 8过好像这样会爆warning的

Murphy's Law :
If there are two or more ways to do something, and one of those ways can result in a catastrophe, then someone will do it.
2008-07-04 11:30
lingluoz
Rank: 2
来 自:苏州科技学院
等 级:新手上路
威 望:4
帖 子:749
专家分:0
注 册:2008-2-2
得分:0 
额。。竟然不会报warning的搞。失误了
恩。。最简单的switch的例子就是
int a;
switch(a) {
case 1:
    puts("the number is 1");
    break;
case 2:
    puts("the number is 2");
    break;
default:
    puts("the number is neither 1 or 2");
    break;
}

注意 在每个case的最后一行 都要有一个break;
否则会继续执行下一个case的语句。。
恩。。

Murphy's Law :
If there are two or more ways to do something, and one of those ways can result in a catastrophe, then someone will do it.
2008-07-04 11:42
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
// 通常是这样
void fastcopy(BYTE *pdest, BYTE *psrc, long count)
{
    int n;

    n = count / 8;
    do
    {
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
        *pdest++ = *psrc++;
    } while (--n > 0);

    n = count % 8;
    do { *pdest++ = *psrc++; } while (--n > 0);
}

// 然而这样更快,也更新颖
// 只是大家没有能够理解而已
void fastcopy(BYTE *pdest, BYTE *psrc, long count)
{
    int n;

    n = (count + 7) / 8;
    switch (count % 8)
    {
    case 0: do { *pdest++ = *psrc++;
    case 7:      *pdest++ = *psrc++;
    case 6:      *pdest++ = *psrc++;
    case 5:      *pdest++ = *psrc++;
    case 4:      *pdest++ = *psrc++;
    case 3:      *pdest++ = *psrc++;
    case 2:      *pdest++ = *psrc++;
    case 1:      *pdest++ = *psrc++;
               } while (--n > 0);
    }
}

的确是一个很别致的代码,大家认真体会就是了。剩余数据的拷贝在第一次 do-while 循环中被执行,以后的循环中,每次循环都是拷贝了 8 个字节。switch 语句根据 count % 8 来转到相应位置,而转到的位置执行到 while 一句时,则是刚好将剩余数据拷贝完毕。这样做巧妙的减少了剩余数据拷贝时,所做的循环判断,因此其效率会比上面的算法快,然而这样的性能提升其实是微不足道的,而且这样的代码也不适合用于工程上。更加关键的是,这段代码的实际效率很大程度的依赖于编译器对 switch 语句的编译和优化处理。

所谓 Duff's Device 说的也就是这个意思。
2008-07-04 20:35



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-222455-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.203840 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved