[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH] fields.c: Avoid unnecessary translations for error messages


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,

From 88dd21620509fd72eab402e3a871203cec406c72 Mon Sep 17 00:00:00 2001
From: Niels Thykier <niels@thykier.net>
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

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 <niels@thykier.net>
 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)
                 _("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)
+  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);
@@ -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);
@@ -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_add_buf(&version, versionstart, versionlength);
+        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);
         while (c_isspace(*p))

Reply to: