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>