How to write a better strlen function?

后端 未结 7 1913
Happy的楠姐
Happy的楠姐 2020-12-30 06:43

I am reading \"Write Great Code Volume 2\" and it shows the following strlen impelementation:

int myStrlen( char *s )
{
    char *start;
    start = s;
    w         


        
相关标签:
7条回答
  • 2020-12-30 07:38

    The following should be faster than the naive algorithm and work for 32/64 bit.

    union intptr {
        char* c;
        long* l;
    #define LSIZE sizeof(long)
    };
    
    #define aligned_(x, a) \
        ((unsigned long) (x) % (a) == 0)
    
    #define punpktt_(x, from, to) \
        ((to) (-1)/(from) (-1)*(from) (x))
    #define punpkbl_(x) \
        punpktt_(x, unsigned char, unsigned long)
    
    #define plessbl_(x, y) \
        (((x) - punpkbl_(y)) & ~(x) & punpkbl_(0x80))
    #define pzerobl_(x) \
        plessbl_(x, 1)
    
    static inline unsigned long maskffs_(unsigned long x)
    {
        unsigned long acc = 0x00010203UL;
        if (LSIZE == 8)
           acc = ((acc << 16) << 16) | 0x04050607UL;
        return ((x & -x) >> 7) * acc >> (LSIZE*8-8);
    }
    
    size_t strlen(const char* base)
    {
        union intptr p = { (char*) base };
        unsigned long mask;
    
        for ( ; !aligned_(p.c, LSIZE); p.c++ )
            if (*p.c == 0)
                return p.c - base;
    
        while ( !(mask = pzerobl_(*p.l)) )
            p.l++;
        return p.c - base + maskffs_(mask);
    }
    
    0 讨论(0)
提交回复
热议问题