今天长见识了

    先是读《Programming in Lua》第9章讲 coroutine,然后去google coroutine,找到 Simon Tatham写的 一篇 coroutine in c,讲怎么在C语言中实现 coroutine,文中 先ugly地基于栈实现了一个:
int  function( void ) {
    
static   int  i, state  =   0 ;
    
switch  (state) {
        
case   0 goto  LABEL0;
        
case   1 goto  LABEL1;
    }
    LABEL0: 
/*  start of function  */
    
for  (i  =   0 ; i  <   10 ; i ++ ) {
        state 
=   1 /*  so we will come back to LABEL1  */
        
return  i;
        LABEL1:; 
/*  resume control straight after the return  */
    }
}

这个方法简单,但是相当丑陋,你必须手工维护这些标签。然后提到了Duff's Device技巧:
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  ((count  -=   8 >   0 );
    }

这段代码能编译通过吗?能的,不信你试试,这是一段用于拷贝数组的代码,我们一般拷贝数组是这样做的:
send(to, from, count)
        register 
short   * to,  * from;
        register count;
        {
                
do
                        
* to  =   * from ++ ;
                
while ( -- count > 0 );
        }
如果循环的中的操作足够快,那么其实大部分时间都是浪费在判断循环条件上面的,而通过Duff's Device通过switch语句将要进行的连续循环操作的次数进行了预判(根据擦case语句的位置)然后依次执行,而不必每次都去进 行测试条件,从而加速循环。这个技巧怎么应用于实现更优雅的 coroutine呢?看代码

int  function( void ) {
    
static   int  i, state  =   0 ;
    
switch  (state) {
        
case   0 /*  start of function  */
        
for  (i  =   0 ; i  <   10 ; i ++ ) {
            state 
=   1 /*  so we will come back to "case 1"  */
            
return  i;
            
case   1 :;  /*  resume control straight after the return  */
        }
    }
}
更好的方式是使用宏:
#define  crBegin static int state=0; switch(state) { case 0:
#define  crReturn(i,x) do { state=i; return x; case i:; } while (0)
#define  crFinish }
int  function( void ) {
    
static   int  i;
    crBegin;
    
for  (i  =   0 ; i  <   10 ; i ++ )
        crReturn(
1 , i);
    crFinish;
}



你可能感兴趣的:(今天长见识了)