Hi, Attached patch reduces the "start up" time of dpkg-query by 10% to 20% (depending on whether you run it under C-locale or not). On a system with about ~1.4k packages installed (and a non-C locale), this is the difference between ~0.050s to ~0.040s per dpkg-query call.
Thanks for considering, ~Niels
From 88dd21620509fd72eab402e3a871203cec406c72 Mon Sep 17 00:00:00 2001 From: Niels Thykier <[email protected]> Date: Sun, 2 Apr 2017 13:28:08 +0000 Subject: [PATCH] fields.c: Avoid unnecessary translations for error messages When dpkg-query is parsing the status database, simply looking up translations for error messages (that are never emitted) takes up ~20% of time with a "non-C" locale (under the C locale, it is closer to ~10%). This change is a simple refactoring to ensure we only do the look up once without having to shuffle too much code around. Signed-off-by: Niels Thykier <[email protected]> --- lib/dpkg/fields.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/dpkg/fields.c b/lib/dpkg/fields.c index 6d13edc50..954bdd7fd 100644 --- a/lib/dpkg/fields.c +++ b/lib/dpkg/fields.c @@ -240,6 +240,9 @@ f_status(struct pkginfo *pkg, struct pkgbin *pkgbin, struct parsedb_state *ps, const char *value, const struct fieldinfo *fip) { + static const char *error_msg1; + static const char *error_msg2; + static const char *error_msg3; if (ps->flags & pdb_rejectstatus) parse_error(ps, _("value for '%s' field not allowed in this context"), @@ -247,12 +250,18 @@ f_status(struct pkginfo *pkg, struct pkgbin *pkgbin, if (ps->flags & pdb_recordavailable) return; + if (!error_msg1) { + error_msg1 = _("first (want) word in 'Status' field"); + error_msg2 = _("second (error) word in 'Status' field"); + error_msg3 = _("third (status) word in 'Status' field"); + } + pkg->want = parse_nv(ps, PARSE_NV_NEXT, &value, wantinfos, - _("first (want) word in 'Status' field")); + error_msg1); pkg->eflag = parse_nv(ps, PARSE_NV_NEXT, &value, eflaginfos, - _("second (error) word in 'Status' field")); + error_msg2); pkg->status = parse_nv(ps, PARSE_NV_LAST, &value, statusinfos, - _("third (status) word in 'Status' field")); + error_msg3); } void @@ -260,9 +269,12 @@ f_version(struct pkginfo *pkg, struct pkgbin *pkgbin, struct parsedb_state *ps, const char *value, const struct fieldinfo *fip) { + static const char *error_msg; + if (!error_msg) { + error_msg = _("error in '%s' field string '%.250s'"); + } parse_db_version(ps, &pkgbin->version, value, - _("error in '%s' field string '%.250s'"), - "Version", value); + error_msg, "Version", value); } void @@ -393,6 +405,7 @@ f_dependency(struct pkginfo *pkg, struct pkgbin *pkgbin, const char *depnamestart, *versionstart; int depnamelength, versionlength; static struct varbuf depname, version; + static const char *db_version_error_msg; struct dependency *dyp, **ldypp; struct deppossi *dop, **ldopp; @@ -577,9 +590,12 @@ f_dependency(struct pkginfo *pkg, struct pkgbin *pkgbin, varbuf_reset(&version); varbuf_add_buf(&version, versionstart, versionlength); varbuf_end_str(&version); + if (!db_version_error_msg) { + db_version_error_msg = _("'%s' field, reference to '%.255s': " + "error in version"); + } parse_db_version(ps, &dop->version, version.buf, - _("'%s' field, reference to '%.255s': " - "error in version"), fip->name, depname.buf); + db_version_error_msg, fip->name, depname.buf); p++; while (c_isspace(*p)) p++; -- 2.11.0

