glibc 中的 strlen 高效实现

 

代码
#include <string.h>
#include 
<stdlib.h>

#undef strlen

/* Return the length of the null-terminated string STR.  Scan for
   the null terminator quickly by testing four bytes at a time.  
*/
size_t strlen(
const char *str) {
    
const char *char_ptr;
    
const unsigned long int *longword_ptr;
    unsigned 
long int longword, himagic, lomagic;

    
/* Handle the first few characters by reading one character at a time.
       Do this until CHAR_PTR is aligned on a longword boundary.  
*/
    
for (char_ptr = str; ((unsigned long int) char_ptr
            
& (sizeof (longword) - 1)) != 0;
            
++char_ptr)
        
if (*char_ptr == '\0')
            
return char_ptr - str;

    
/* All these elucidatory comments refer to 4-byte longwords,
       but the theory applies equally well to 8-byte longwords.  
*/

    longword_ptr 
= (unsigned long int *) char_ptr;

    
/* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
       the "holes."  Note that there is a hole just to the left of
       each byte, with an extra at the end:

       bits:  01111110 11111110 11111110 11111111
       bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD

       The 1-bits make sure that carries propagate to the next 0-bit.
       The 0-bits provide holes for carries to fall into.  
*/
    himagic 
= 0x80808080L;
    lomagic 
= 0x01010101L;
    
if (sizeof (longword) > 4) {
        
/* 64-bit version of the magic.  */
        
/* Do the shift in two steps to avoid a warning if long has 32 bits.  */
        himagic 
= ((himagic << 16<< 16| himagic;
        lomagic 
= ((lomagic << 16<< 16| lomagic;
    }
    
if (sizeof (longword) > 8)
        abort();

    
/* Instead of the traditional loop which tests each character,
       we will test a longword at a time.  The tricky part is testing
       if *any of the four* bytes in the longword in question are zero.  
*/
    
for (;;) {
        longword 
= *longword_ptr++;

        
if (((longword - lomagic) & ~longword & himagic) != 0) {
            
/* Which of the bytes was the zero?  If none of them were, it was
               a misfire; continue the search.  
*/

            
const char *cp = (const char *) (longword_ptr - 1);

            
if (cp[0== 0)
                
return cp - str;
            
if (cp[1== 0)
                
return cp - str + 1;
            
if (cp[2== 0)
                
return cp - str + 2;
            
if (cp[3== 0)
                
return cp - str + 3;
            
if (sizeof (longword) > 4) {
                
if (cp[4== 0)
                    
return cp - str + 4;
                
if (cp[5== 0)
                    
return cp - str + 5;
                
if (cp[6== 0)
                    
return cp - str + 6;
                
if (cp[7== 0)
                    
return cp - str + 7;
            }
        }
    }
}
/* 说明
(1) 一次判断一个字符直到内存对齐,如果在内存对齐之前就遇到'\0'则直接return,否则到(2);
(2) 一次读入并判断一个DWORD,如果此DWORD中没有为0的字节,则继续下一个DWORD,否则到(3);
(3) 到这里则说明DWORD中至少有一个字节为0,剩下的就是找出第一个为0的字节的位置然后return。
*/
 


 

 

posted on 2010-07-12 15:34  庄冠华  阅读(334)  评论(0编辑  收藏  举报

导航