On Sat, Oct 27, 2001 at 02:56:07PM +0400, Alexander V. Lukyanov wrote:
> I've rewrote crlf_to_lf so it is more clear and easier to understand.
> 
> int crlf_to_lf(char *buf, int s)
> {
>    char *store=mem_crlf(buf,s);
>    if(!store)
>       return s;
> 
>    int retsize=s-1;
>    s-=store+1-buf;
>    buf=store+1;
> 
>    while(s>1)
>    {
>       char *crlf=mem_crlf(buf,s);
>       if(!crlf)
>        break;
> 
>       memmove(store, buf, crlf-buf);
>       store+=crlf-buf;
>       retsize--;
>       s-=crlf+1-buf;
>       buf=crlf+1;
>    }
>    memmove(store,buf,s);
>    return retsize;
> }

Both of ours are easier to understand for each of us, only because we
wrote them.  I can't quickly make sense of that, either. :)

Originally, I used memmove/memchr for speed--they're well-optimized.  In
retrospect, that's also iterating over the input buffer twice (though in
a cache-friendly way.)

Here's one that anyone can understand:

int crlf_to_lf(char *buf, int s)
{
        char *store = buf;
        int retsiz = s;
        while(s) {
                if(s-- > 1 && buf[0] == '\r' && buf[1] == '\n') {
                        buf++;
                        retsiz--;
                        continue;
                }
                *store++ = *buf++;
        }
        return retsiz;
}

It's about twice as fast when the buffer is a lot of short lines--which is
the typical case of NLIST.  The memchr/memmove approach is about 30% faster
for longer strings (ie. 80 characters/line, which would be the case if
it was used for LIST); apparently the word-reading optimizations used
by memchr and memmove offset the penalty of iterating twice.

At 64 bytes/line for 10 megs of data, on my system, it's still 300ms.
The speed difference doesn't really matter.

-- 
Glenn Maynard

Reply via email to