This is an automated email from the git hooks/post-receive script. guillem pushed a commit to branch master in repository dpkg.
View the commit online: https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=2f3d0546617f510a0e9a976d897fd1cd91408d12 commit 2f3d0546617f510a0e9a976d897fd1cd91408d12 Author: Guillem Jover <[email protected]> AuthorDate: Sat Feb 23 04:52:18 2019 +0100 libdpkg: New benchmark programs and infrastructure These are intended to be used to check performance improvements in the libdpkg implementation. --- debian/changelog | 1 + lib/dpkg/Makefile.am | 1 + lib/dpkg/fsys-hash.c | 39 +++++++++++++++++++++++ lib/dpkg/fsys.h | 4 +++ lib/dpkg/perf.h | 71 ++++++++++++++++++++++++++++++++++++++++++ lib/dpkg/pkg-hash.c | 15 +++++++-- lib/dpkg/t/.gitignore | 5 +++ lib/dpkg/t/Makefile.am | 7 +++++ lib/dpkg/t/b-fsys-hash.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/dpkg/t/b-pkg-hash.c | 65 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 286 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 90edb01b0..c73e7012f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -44,6 +44,7 @@ dpkg (1.19.5) UNRELEASED; urgency=medium - dpkg: Switch force options from individual variables to bit fields. - dpkg: Switch from a char to an enum to track the force options types. - dpkg: Switch to set the default force option from the forceinfos array. + - libdpkg: New benchmark programs and infrastructure. * Build system: - Check whether this dist is a release, based only on the version format. This will avoid having to do a two staged release to get a proper perl diff --git a/lib/dpkg/Makefile.am b/lib/dpkg/Makefile.am index a2828af4b..3a3bd64b4 100644 --- a/lib/dpkg/Makefile.am +++ b/lib/dpkg/Makefile.am @@ -86,6 +86,7 @@ libdpkg_la_SOURCES = \ parsehelp.c \ path.c \ path-remove.c \ + perf.h \ pkg.c \ pkg-array.c \ pkg-files.c \ diff --git a/lib/dpkg/fsys-hash.c b/lib/dpkg/fsys-hash.c index cb173bb9a..88ec47e4a 100644 --- a/lib/dpkg/fsys-hash.c +++ b/lib/dpkg/fsys-hash.c @@ -127,6 +127,45 @@ fsys_hash_find_node(const char *name, enum fsys_hash_find_flags flags) return newnode; } +void +fsys_hash_report(FILE *file) +{ + struct fsys_namenode *node; + int i, c; + int *freq; + int empty = 0, used = 0, collided = 0; + + freq = m_malloc(sizeof(freq[0]) * nfiles + 1); + for (i = 0; i <= nfiles; i++) + freq[i] = 0; + for (i = 0; i < BINS; i++) { + for (c = 0, node = bins[i]; node; c++, node = node->next); + fprintf(file, "fsys-hash: bin %5d has %7d\n", i, c); + if (c == 0) + empty++; + else if (c == 1) + used++; + else { + used++; + collided++; + } + freq[c]++; + } + for (i = nfiles; i > 0 && freq[i] == 0; i--); + while (i >= 0) { + fprintf(file, "fsys-hash: size %7d occurs %5d times\n", + i, freq[i]); + i--; + } + fprintf(file, "fsys-hash: bins empty %d\n", empty); + fprintf(file, "fsys-hash: bins used %d (collided %d)\n", used, + collided); + + m_output(file, "<hash report>"); + + free(freq); +} + /* * Forward iterator. */ diff --git a/lib/dpkg/fsys.h b/lib/dpkg/fsys.h index 67fce2ad2..8b9107472 100644 --- a/lib/dpkg/fsys.h +++ b/lib/dpkg/fsys.h @@ -22,6 +22,8 @@ #ifndef LIBDPKG_FSYS_H #define LIBDPKG_FSYS_H +#include <stdio.h> + #include <dpkg/file.h> /* @@ -167,6 +169,8 @@ void fsys_hash_init(void); void fsys_hash_reset(void); +void +fsys_hash_report(FILE *file); int fsys_hash_entries(void); diff --git a/lib/dpkg/perf.h b/lib/dpkg/perf.h new file mode 100644 index 000000000..c7d9301a8 --- /dev/null +++ b/lib/dpkg/perf.h @@ -0,0 +1,71 @@ +/* + * libdpkg - Debian packaging suite library routines + * perf.h - performance testing support + * + * Copyright © 2009-2019 Guillem Jover <[email protected]> + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef LIBDPKG_PERF_H +#define LIBDPKG_PERF_H + +#include <config.h> +#include <compat.h> + +#include <time.h> +#include <stdio.h> + +struct perf_slot { + struct timespec t_ini, t_end; +}; + +static inline void +perf_ts_sub(struct timespec *a, struct timespec *b, struct timespec *res) +{ + res->tv_sec = a->tv_sec - b->tv_sec; + res->tv_nsec = a->tv_nsec - b->tv_nsec; + if (res->tv_nsec < 0) { + res->tv_sec--; + res->tv_nsec += 1000000000; + } +} + +static void +perf_ts_mark_print(const char *str) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + printf("%lu.%.9lu: %s\n", ts.tv_sec, ts.tv_nsec, str); +} + +static void +perf_ts_slot_print(struct perf_slot *ps, const char *str) +{ + struct timespec t_res; + + perf_ts_sub(&ps->t_end, &ps->t_ini, &t_res); + + printf("%lu.%.9lu: %s (%lu.%.9lu sec)\n", + ps->t_end.tv_sec, ps->t_end.tv_nsec, + str, t_res.tv_sec, t_res.tv_nsec); +} + +#define perf_ts_slot_start(ps) clock_gettime(CLOCK_MONOTONIC, &((ps)->t_ini)) +#define perf_ts_slot_stop(ps) clock_gettime(CLOCK_MONOTONIC, &((ps)->t_end)) + +#endif diff --git a/lib/dpkg/pkg-hash.c b/lib/dpkg/pkg-hash.c index e7de951b0..34b2f5b23 100644 --- a/lib/dpkg/pkg-hash.c +++ b/lib/dpkg/pkg-hash.c @@ -372,20 +372,31 @@ pkg_hash_report(FILE *file) int i, c; struct pkgset *pkg; int *freq; + int empty = 0, used = 0, collided = 0; freq = m_malloc(sizeof(int) * nset + 1); for (i = 0; i <= nset; i++) freq[i] = 0; for (i=0; i<BINS; i++) { for (c=0, pkg= bins[i]; pkg; c++, pkg= pkg->next); - fprintf(file,"bin %5d has %7d\n",i,c); + fprintf(file, "pkg-hash: bin %5d has %7d\n", i, c); + if (c == 0) + empty++; + else if (c == 1) + used++; + else { + used++; + collided++; + } freq[c]++; } for (i = nset; i > 0 && freq[i] == 0; i--); while (i >= 0) { - fprintf(file, "size %7d occurs %5d times\n", i, freq[i]); + fprintf(file, "pkg-hash: size %7d occurs %5d times\n", i, freq[i]); i--; } + fprintf(file, "pkg-hash: bins empty %d\n", empty); + fprintf(file, "pkg-hash: bins used %d (collided %d)\n", used, collided); m_output(file, "<hash report>"); diff --git a/lib/dpkg/t/.gitignore b/lib/dpkg/t/.gitignore index 5b019c86e..b711dbee7 100644 --- a/lib/dpkg/t/.gitignore +++ b/lib/dpkg/t/.gitignore @@ -1,6 +1,11 @@ +# Benchmarks +b-fsys-hash +b-pkg-hash +# Compiled helpers c-tarextract c-treewalk c-trigdeferred +# Testsuite t-ar t-arch t-buffer diff --git a/lib/dpkg/t/Makefile.am b/lib/dpkg/t/Makefile.am index 83c96f329..ab9ce3b4b 100644 --- a/lib/dpkg/t/Makefile.am +++ b/lib/dpkg/t/Makefile.am @@ -60,8 +60,15 @@ test_scripts = \ t-trigdeferred.t \ $(nil) +BENCHMARK_LDADD_FLAGS = -lrt $(LDADD) + +b_fsys_hash_LDADD = $(BENCHMARK_LDADD_FLAGS) +b_pkg_hash_LDADD = $(BENCHMARK_LDADD_FLAGS) + check_PROGRAMS = \ $(test_programs) \ + b-fsys-hash \ + b-pkg-hash \ c-tarextract \ c-treewalk \ c-trigdeferred \ diff --git a/lib/dpkg/t/b-fsys-hash.c b/lib/dpkg/t/b-fsys-hash.c new file mode 100644 index 000000000..373cfc7c6 --- /dev/null +++ b/lib/dpkg/t/b-fsys-hash.c @@ -0,0 +1,80 @@ +/* + * dpkg - main program for package management + * b-fsys-hash.c - test fsys database load and hash performance + * + * Copyright © 2009-2019 Guillem Jover <[email protected]> + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> +#include <compat.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> + +#include <dpkg/i18n.h> +#include <dpkg/dpkg.h> +#include <dpkg/dpkg-db.h> + +#include <dpkg/perf.h> + +#include <dpkg/db-fsys.h> + +static const char *admindir; + +int +main(int argc, const char *const *argv) +{ + struct perf_slot ps; + + push_error_context(); + setvbuf(stdout, NULL, _IONBF, 0); + + admindir = dpkg_db_set_dir(admindir); + + perf_ts_mark_print("init"); + + perf_ts_slot_start(&ps); + fsys_hash_init(); + perf_ts_slot_stop(&ps); + + perf_ts_slot_print(&ps, "fsys_hash_init"); + + perf_ts_slot_start(&ps); + modstatdb_open(msdbrw_readonly | msdbrw_available_readonly); + perf_ts_slot_stop(&ps); + + perf_ts_slot_print(&ps, "modstatdb_init"); + + perf_ts_slot_start(&ps); + ensure_allinstfiles_available_quiet(); + perf_ts_slot_stop(&ps); + + perf_ts_slot_print(&ps, "load .list"); + + pkg_hash_report(stdout); + fsys_hash_report(stdout); + + modstatdb_shutdown(); + pop_error_context(ehflag_normaltidy); + + perf_ts_mark_print("shutdown"); + + return 0; +} diff --git a/lib/dpkg/t/b-pkg-hash.c b/lib/dpkg/t/b-pkg-hash.c new file mode 100644 index 000000000..74e26af7b --- /dev/null +++ b/lib/dpkg/t/b-pkg-hash.c @@ -0,0 +1,65 @@ +/* + * dpkg - main program for package management + * b-pkg-hash.c - test pkg database load and hash performance + * + * Copyright © 2009-2019 Guillem Jover <[email protected]> + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> +#include <compat.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> + +#include <dpkg/i18n.h> +#include <dpkg/dpkg.h> +#include <dpkg/dpkg-db.h> + +#include <dpkg/perf.h> + +static const char *admindir; + +int +main(int argc, const char *const *argv) +{ + struct perf_slot ps; + + push_error_context(); + setvbuf(stdout, NULL, _IONBF, 0); + + admindir = dpkg_db_set_dir(admindir); + + perf_ts_mark_print("init"); + + perf_ts_slot_start(&ps); + modstatdb_open(msdbrw_readonly | msdbrw_available_readonly); + perf_ts_slot_stop(&ps); + + perf_ts_slot_print(&ps, "modstatdb_init"); + + pkg_hash_report(stdout); + + modstatdb_shutdown(); + pop_error_context(ehflag_normaltidy); + + perf_ts_mark_print("shutdown"); + + return 0; +} -- Dpkg.Org's dpkg

