diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2020-02-29 18:35:55 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2020-02-29 18:52:04 -0500 |
commit | 1c184e718f5745cf3a53a3c389814a792e73aa51 (patch) | |
tree | 0959d07a8e4ac507aefa4867156d144ce2eff1dd /printf.c | |
parent | 7fbf673ae2db33d6e47386bf3169d4b48f0fc8b4 (diff) | |
download | bfs-1c184e718f5745cf3a53a3c389814a792e73aa51.tar.xz |
passwd: Cache the user/group tables
This is a significant optimization for conditions that need these
tables:
Benchmark #1: ./bfs ~/code/linux -nouser >/dev/null
Time (mean ± σ): 232.0 ms ± 2.5 ms [User: 44.3 ms, System: 185.0 ms]
Range (min … max): 228.7 ms … 238.7 ms 12 runs
Benchmark #2: ./bfs-1.6 ~/code/linux -nouser >/dev/null
Time (mean ± σ): 1.050 s ± 0.012 s [User: 544.2 ms, System: 500.0 ms]
Range (min … max): 1.025 s … 1.063 s 10 runs
Benchmark #3: find ~/code/linux -nouser >/dev/null
Time (mean ± σ): 1.040 s ± 0.012 s [User: 533.6 ms, System: 500.6 ms]
Range (min … max): 1.017 s … 1.054 s 10 runs
Summary
'./bfs ~/code/linux -nouser >/dev/null' ran
4.48 ± 0.07 times faster than 'find ~/code/linux -nouser >/dev/null'
4.52 ± 0.07 times faster than './bfs-1.6 ~/code/linux -nouser >/dev/null'
Diffstat (limited to 'printf.c')
-rw-r--r-- | printf.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -21,6 +21,7 @@ #include "dstring.h" #include "expr.h" #include "mtab.h" +#include "passwd.h" #include "stat.h" #include "time.h" #include "util.h" @@ -45,8 +46,8 @@ struct bfs_printf { enum bfs_stat_field stat_field; /** Character data associated with this directive. */ char c; - /** The current mount table. */ - const struct bfs_mtab *mtab; + /** Some data used by the directive. */ + const void *ptr; /** The next printf directive in the chain. */ struct bfs_printf *next; }; @@ -217,7 +218,7 @@ static int bfs_printf_F(FILE *file, const struct bfs_printf *directive, const st return -1; } - const char *type = bfs_fstype(directive->mtab, statbuf); + const char *type = bfs_fstype(directive->ptr, statbuf); return fprintf(file, directive->str, type); } @@ -239,7 +240,8 @@ static int bfs_printf_g(FILE *file, const struct bfs_printf *directive, const st return -1; } - struct group *grp = getgrgid(statbuf->gid); + const struct bfs_groups *groups = directive->ptr; + const struct group *grp = groups ? bfs_getgrgid(groups, statbuf->gid) : NULL; if (!grp) { return bfs_printf_G(file, directive, ftwbuf); } @@ -410,7 +412,8 @@ static int bfs_printf_u(FILE *file, const struct bfs_printf *directive, const st return -1; } - struct passwd *pwd = getpwuid(statbuf->uid); + const struct bfs_users *users = directive->ptr; + const struct passwd *pwd = users ? bfs_getpwuid(users, statbuf->uid) : NULL; if (!pwd) { return bfs_printf_U(file, directive, ftwbuf); } @@ -512,7 +515,7 @@ static struct bfs_printf *new_directive(bfs_printf_fn *fn) { } directive->stat_field = 0; directive->c = 0; - directive->mtab = NULL; + directive->ptr = NULL; directive->next = NULL; return directive; @@ -686,10 +689,15 @@ struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) bfs_error(cmdline, "Couldn't parse the mount table: %s.\n", strerror(cmdline->mtab_error)); goto directive_error; } + directive->ptr = cmdline->mtab; directive->fn = bfs_printf_F; - directive->mtab = cmdline->mtab; break; case 'g': + if (!cmdline->groups) { + bfs_error(cmdline, "Couldn't parse the group table: %s.\n", strerror(cmdline->groups_error)); + goto directive_error; + } + directive->ptr = cmdline->groups; directive->fn = bfs_printf_g; break; case 'G': @@ -738,6 +746,11 @@ struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) directive->stat_field = BFS_STAT_MTIME; break; case 'u': + if (!cmdline->users) { + bfs_error(cmdline, "Couldn't parse the user table: %s.\n", strerror(cmdline->users_error)); + goto directive_error; + } + directive->ptr = cmdline->users; directive->fn = bfs_printf_u; break; case 'U': |