[folks/wip/nielsdg/performance: 4/4] persona: Don't use string.replace




commit 09da86636d8840b685ad3a27f529cf4d9b320f07
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sun Oct 4 15:43:10 2020 +0200

    persona: Don't use string.replace
    
    Although it's supposedly part of `glib-2.0.vapi`, `string.replace` is
    _not_ a function implemented by GLib. Worse, what it does is to create
    and compile a `GRegex`, which then gets used to do the substitution.
    
    Since we call `Persona.build_uid()` for each persona, and then even 3
    times in a row, we create an amount of unnecessary temporary
    allocations that linearly increases with the amount of contacts.
    
    To mitigate this, use a `GString` (aka `GLib.StringBuilder`) and try to
    allocate the right amount from the start.

 folks/persona.vala | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)
---
diff --git a/folks/persona.vala b/folks/persona.vala
index 265669f2..ecbadb9f 100644
--- a/folks/persona.vala
+++ b/folks/persona.vala
@@ -283,11 +283,20 @@ public abstract class Folks.Persona : Object
       assert_not_reached ();
     }
 
-  private static string _escape_uid_component (string component)
+  private static string _add_escaped_uid_component (StringBuilder uid, string component)
     {
       /* Escape colons with backslashes */
-      string escaped = component.replace ("\\", "\\\\");
-      return escaped.replace (":", "\\:");
+      for (int i = 0; i < component.length; i++)
+        {
+          char c = component[i];
+          if (c == ':' || c == '\\')
+            {
+              uid.append_c ('\\');
+            }
+          uid.append_c (c);
+        }
+
+      return uid.str;
     }
 
   private static string _unescape_uid_component (string component)
@@ -316,9 +325,20 @@ public abstract class Folks.Persona : Object
         requires (persona_store_id != "")
         requires (persona_id != "")
     {
-      return "%s:%s:%s".printf (Persona._escape_uid_component (backend_name),
-          Persona._escape_uid_component (persona_store_id),
-          Persona._escape_uid_component (persona_id));
+      long min_total_length = backend_name.length
+          + persona_store_id.length
+          + persona_id.length
+          + 2  // 2 colons
+          + 1; // terminator
+
+      StringBuilder uid = new StringBuilder.sized (min_total_length);
+      Persona._add_escaped_uid_component (uid, backend_name);
+      uid.append_c (':');
+      Persona._add_escaped_uid_component (uid, persona_store_id);
+      uid.append_c (':');
+      Persona._add_escaped_uid_component (uid, persona_id);
+
+      return uid.str;
     }
 
   /**


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