contiki之知识储备1:达夫设备(duff's device)

概述

上个世纪80年代突然出现下面这么一段程序

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);                      
    }  
这是一段吓死人的程序,特别是某些大公司里面的经过编程规范“特训”过的战士。这就是传说中的达夫设备(duff's device)。你能想象和敢想象switch还能这么用吗?当时 Tom Duff这么用是为了增加内存复制的效率。因为正常情况下内存复制应该是这样的:

for(i=0; i<n; i++)
    *to++ = *from++;
但是这样复制的话,每次执行一行就会判断一次,影响效率。而达夫设备可以执行8次才需要判断一次,这样就可以明显提高效率。但是,如果你真想提高效率的话,如果给你老板看到的话,估计你就要被炒掉了。但是这样可以给我们下面两个启示。

启示1★新的复制方法

这点启示主要来自于达夫设备的复制方法,他的目的只是想每次循环多执行几次复制,那么为了我们的编码规范,我们可以采用下面的方法:
times = n / 8;
for(i=0; i<n%8; i++)
	*dest++ = *src++;
for(i=0; i<times; i++)
{
	*dest++ = *src++;	
	*dest++ = *src++;	
	*dest++ = *src++;	
	*dest++ = *src++;	
	*dest++ = *src++;	
	*dest++ = *src++;	
	*dest++ = *src++;	
	*dest++ = *src++;	
}

启示2★在switch里面随意增加控制语句

对于达夫设备,之所以难以接受这样的代码,是因为以前没有人告诉我们case语句之间可以随意添加控制语句。比如下面的语句:
#include <stdio.h>

int main()
{
	int i;
	for(i=0; i<10; i++)
	{
		switch(i)
		{
			default:if(i%2)
					break;
			case 100:
				printf("%d\t", i);	
		}
	}
}
结果会输出:0 2 4 6 8

小结

首先,这里介绍达夫设备并不意味着我推荐使用它。他就像goto语句一样,现在沟通语句基本已经绝迹了吧!我们的C语言一般都会说goto语句会带来多少多少灾难性的后果,推荐我们不到必要的时候不要使用它。一般我们看到上面那句话估计以后就不会再使用goto语句了。因为我们都怕麻烦。
但是呢,我们看linux内核,tcp/ip协议栈,随处可见的goto语句,你看我们的linux内核,网络不是运行得很好嘛。而这个达夫设备呢,它比goto语句复杂,但是确可以在很多编译器通过,至少VC和gcc可以过。有句很经典的话,“存在即合理”。既然goto语句和switch语句嵌套控制语句是可行的,了解了解也是可以的。方便的时候,用用也是不错的。(如果说推荐估计给人喷死了!%>_<%~~~)
再再但是呢,有两位大神还真用达夫设备解决了两个大问题。其中有一个还用得不亦乐乎(O(∩_∩)O哈哈~)。
预知后事如何,请看这篇博文:






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值