Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Jul 2007 17:39:26 -0700
From:      Garrett Cooper <youshi10@u.washington.edu>
To:        Tim Kientzle <kientzle@freebsd.org>
Cc:        ports@freebsd.org, hackers@freebsd.org, krion@freebsd.org
Subject:   Re: Finding slowdowns in	pkg_install	(continuations	of	previous	threads)
Message-ID:  <46996CBE.6050401@u.washington.edu>
In-Reply-To: <469967A8.3080901@freebsd.org>
References:  <468C96C0.1040603@u.washington.edu>	<468C9718.1050108@u.washington.edu>	<468E60E9.80507@freebsd.org>	<468E6C81.4060908@u.washington.edu>	<468E7192.8030105@freebsd.org>	<4696C0D2.6010809@u.washington.edu>	<4697A210.2020301@u.washington.edu> <4698ADB5.7080600@u.washington.edu> <4698F98A.6080908@freebsd.org> <4699587F.30703@u.washington.edu> <469967A8.3080901@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Tim Kientzle wrote:
>>    The following blog post has all of my commentary on the results I 
>> have: 
>> <http://blogs.freebsdish.org/gcooper/2007/07/14/modifications-to-pkg_install-the-positive-and-negative-implications/>. 
>
>
>> I tried to unroll strcmp a bit by checking for the first character of 
>> the
> > command, then run strcmp ...
>
> There's a somewhat more straightforward optimization that
> relies on this same idea:
>
> switch(cmd[0]) {
> case 'c':
>     /* Commands that start with 'c' */
>     if (strcmp(cmd, 'cwd') == 0)
>     return (CMD_CWD);
>     /* FALLTHROUGH */
> case 'd':
>     /* Commands that start with 'd' */
>
>     .... etc....
>     /* FALLTHROUGH */
> default:
>     /* Unrecognized command. */
> }
>
> This is a little cleaner and easier to read
> and may even be faster than the code you
> presented in your blog.  Note that the fall through
> ensures that all unrecognized commands end up at
> the same place.  If unrecognized commands are
> very rare (they should be), then the fallthrough
> is not a performance issue.
>
>> /** malloc buffer large enough to hold +CONTENTS **/
>>
>> while(!feof(file_p)) {
>>
>>     /** add content via fgetc **/
>> }
>
> Yuck.  Try this instead:
>
>    struct stat st;
>    int fd;
>    char *buff;
>
>    fd = open(file);
>    fstat(fd, &st);
>    buff = malloc(st.st_size + 1);
>    read(fd, buff, st.st_size);
>    buff[st.st_size] = '\0';
>    close(fd);
>
> Plus some error checking, of course.  You can
> use stdio if you prefer:
>
>    FILE *f;
>
>    f = fopen(file, "r");
>    fstat(fileno(f), &st);
>    buff = malloc(st.st_size + 1);
>    fread(buff, 1, st.st_size, f);
>    buff[st.st_size] = '\0';
>    fclose(f);
>
> Either way, this is a lot more efficient than
> tens of thousands of calls to fgetc().
>
> Cheers,
>
> Tim Kientzle
Tim,
    That was a very good call. I didn't even think of read(2) over fgetc(2).
    That decreased the overall time by 0.7 seconds in installing vim, 
which is just a little shy of a 10% speedup.
-Garrett



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?46996CBE.6050401>