[KPhotoAlbum] Startup performance

Robert Krawitz rlk at alum.mit.edu
Tue Oct 13 03:10:43 BST 2020


So I did find one more little point hack; the MD5 conversion from string to 2 uint64's was taking
almost 3.5% of the startup time (!).  By doing the calculation explicitly I got it down to 0.5%; the
savings based on kcachegrind cycle estimation was 2.75% and that's roughly what I got from careful
wallclock time.

It's ugly, but I don't think it makes any unwarranted assumptions that the current code doesn't
make.  I'm checking that the length is 32 characters so it won't crash and at least making sure the
characters are within range 0-9 and a-f/A-F (treat them as zero otherwise).  That's no worse than
the current code, which doesn't check that the conversion is valid.  It amounts to about 0.2 second
on startup, which isn't exactly much, but...

On the other hand, if people judge this to be too risky, I won't pursue it.  I did test it by
load/save and verifying that there were no relevant changes (a couple of my tokens switched
ordering, but the images in my database did not change).

diff --git a/DB/MD5.cpp b/DB/MD5.cpp
index 9eaff54e..35b09422 100644
--- a/DB/MD5.cpp
+++ b/DB/MD5.cpp
@@ -37,11 +37,43 @@ DB::MD5::MD5()
 {
 }

+#define QC(c) ((((c).toLatin1()) & 0x7f))
+#define QA(c) ((((c).toLatin1()) & 0x5f))
+
+#define ISNUM(c) (QC(c) >= '0' && QC(c) <= '9')
+#define TONUM(c) (QC(c) - '0')
+#define ISAL(c) ((qulonglong) (QA(c) >= 'A' && QA(c) <= 'F'))
+#define TOALNUM(c) ((qulonglong) (QA(c) - 'A' + 10))
+#define CHARTOHEX(c, s) ((ISNUM(c) ? TONUM(c) : (ISAL(c) ? TOALNUM(c) : 0)) << (s))
+
+#define TOULONGLONG(r, o)                       \
+    (CHARTOHEX((r)[(o)+ 0], 60) +               \
+     CHARTOHEX((r)[(o)+ 1], 56) +               \
+     CHARTOHEX((r)[(o)+ 2], 52) +               \
+     CHARTOHEX((r)[(o)+ 3], 48) +               \
+     CHARTOHEX((r)[(o)+ 4], 44) +               \
+     CHARTOHEX((r)[(o)+ 5], 40) +               \
+     CHARTOHEX((r)[(o)+ 6], 36) +               \
+     CHARTOHEX((r)[(o)+ 7], 32) +               \
+     CHARTOHEX((r)[(o)+ 8], 28) +               \
+     CHARTOHEX((r)[(o)+ 9], 24) +               \
+     CHARTOHEX((r)[(o)+10], 20) +               \
+     CHARTOHEX((r)[(o)+11], 16) +               \
+     CHARTOHEX((r)[(o)+12], 12) +               \
+     CHARTOHEX((r)[(o)+13],  8) +               \
+     CHARTOHEX((r)[(o)+14],  4) +               \
+     CHARTOHEX((r)[(o)+15],  0))
+
 DB::MD5::MD5(const QString &md5str)
-    : m_isNull(md5str.isEmpty())
-    , m_v0(md5str.leftRef(16).toULongLong(0, 16))
-    , m_v1(md5str.midRef(16, 16).toULongLong(0, 16))
+    : m_isNull(md5str.length() != 32)
+    , m_v0(0)
+    , m_v1(0)
 {
+    if (! m_isNull) {
+        const QChar *rawData = md5str.constData();
+        m_v0 = TOULONGLONG(rawData, 0);
+        m_v1 = TOULONGLONG(rawData, 16);
+    }
 }

 bool DB::MD5::isNull() const
@@ -51,12 +83,13 @@ bool DB::MD5::isNull() const

 DB::MD5 &DB::MD5::operator=(const QString &md5str)
 {
-    if (md5str.isEmpty()) {
+    if (md5str.length() != 32) {
         m_isNull = true;
     } else {
         m_isNull = false;
-        m_v0 = md5str.leftRef(16).toULongLong(0, 16);
-        m_v1 = md5str.midRef(16, 16).toULongLong(0, 16);
+        const QChar *rawData = md5str.constData();
+        m_v0 = TOULONGLONG(rawData, 0);
+        m_v1 = TOULONGLONG(rawData, 16);
     }
     return *this;
 }



More information about the Kphotoalbum mailing list