学习型 ASP/PHP/ASP.NET 主机 30元/年全能 ASP/PHP/ASP.NET 主机,支持月付专业 MSSQL 数据库空间,支持月付专业 MySQL 数据库空间,支持月付
轻松建立自己的群组,招兵买马   
发新话题
打印

switch语句问题

引用:
StarWing83 在 2008-7-4 08:54 的发言:



看看这份代码,会改变你对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++; 快吧?
为了中国软件工业的未来,有爱心的朋友请不要帮忙代做作业,或者至少是收费服务!如果您不需要钱,或者您不愿收费用于自己,请把收取的钱用于支援山区贫困学生…谢谢大家!

TOP

快一点儿,但主要用来体现switch的功能,这个代码叫做达夫设备(Duff’s Device)。
专心编程………
飞燕算法初级群:3996098
我的Blog

TOP

引用:
StarWing83 在 2008-7-4 09:05 的发言:

快一点儿,但主要用来体现switch的功能,这个代码叫做达夫设备(Duff’s Device)。
但我感觉这个速率的提高不是因为switch,而是少了计数变量的计算
例如for(i=0;i<5;i++) x++; 就慢于++x++,++x++,++x;

[ 本帖最后由 卧龙孔明 于 2008-7-4 09:11 编辑 ]
为了中国软件工业的未来,有爱心的朋友请不要帮忙代做作业,或者至少是收费服务!如果您不需要钱,或者您不愿收费用于自己,请把收取的钱用于支援山区贫困学生…谢谢大家!

TOP

http://blogs.sun.com/weixue/entry/duff_s_device_%E8%BE%BE%E5%A4%AB%E8%AE%BE%E5%A4%87

自己看

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

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

TOP

看了,我说的没错啊,就是减少了判断
为了中国软件工业的未来,有爱心的朋友请不要帮忙代做作业,或者至少是收费服务!如果您不需要钱,或者您不愿收费用于自己,请把收取的钱用于支援山区贫困学生…谢谢大家!

TOP

你后句是对的,但是前一句是“不是因为switch”,很抱歉,减少判断的功臣就是switch。
专心编程………
飞燕算法初级群:3996098
我的Blog

TOP

引用:
StarWing83 在 2008-7-4 09:16 的发言:

你后句是对的,但是前一句是“不是因为switch”,很抱歉,减少判断的功臣就是switch。
为了中国软件工业的未来,有爱心的朋友请不要帮忙代做作业,或者至少是收费服务!如果您不需要钱,或者您不愿收费用于自己,请把收取的钱用于支援山区贫困学生…谢谢大家!

TOP

fall through哦 8过好像这样会爆warning的
MAY 1, 1964 -- The Birth of BASIC
Over 40 years later, it still enables ANYONE to write their own programs.
P.S. 遠離御宅 抵制禁宅

TOP

额。。竟然不会报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的语句。。
恩。。
MAY 1, 1964 -- The Birth of BASIC
Over 40 years later, it still enables ANYONE to write their own programs.
P.S. 遠離御宅 抵制禁宅

TOP

// 通常是这样
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 说的也就是这个意思。

TOP

发新话题