[glib] Optimize g_unichar_iswide



commit 97a25d12031b07540c95387cb434ee5c87b82c46
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Sep 10 23:57:01 2015 -0400

    Optimize g_unichar_iswide
    
    Apply the same optimization that was done for g_unichar_get_script
    long ago: Use a quick check for the low end, and then remember the
    midpoint of the last bsearch, since we're likely to be called for
    characters that are close to each other.
    
    This change made g_unichar_iswide disappear from profiles of the
    gtk3-demo listbox example.

 glib/guniprop.c |   38 ++++++++++++++++++++++++++++++--------
 1 files changed, 30 insertions(+), 8 deletions(-)
---
diff --git a/glib/guniprop.c b/glib/guniprop.c
index 98dff21..0e3b696 100644
--- a/glib/guniprop.c
+++ b/glib/guniprop.c
@@ -433,6 +433,32 @@ interval_compare (const void *key, const void *elt)
   return 0;
 }
 
+#define G_WIDTH_TABLE_MIDPOINT (G_N_ELEMENTS (g_unicode_width_table_wide) / 2)
+
+static inline gboolean
+g_unichar_iswide_bsearch (gunichar ch)
+{
+  int lower = 0;
+  int upper = G_N_ELEMENTS (g_unicode_width_table_wide) + 1;
+  static int saved_mid = G_WIDTH_TABLE_MIDPOINT;
+  int mid = saved_mid;
+
+  do
+    {
+      if (ch < g_unicode_width_table_wide[mid].start)
+       upper = mid - 1;
+      else if (ch > g_unicode_width_table_wide[mid].end)
+       lower = mid + 1;
+      else
+       return TRUE;
+
+      mid = (lower + upper) / 2;
+    }
+  while (lower <= upper);
+
+  return FALSE;
+}
+
 /**
  * g_unichar_iswide:
  * @c: a Unicode character
@@ -445,14 +471,10 @@ interval_compare (const void *key, const void *elt)
 gboolean
 g_unichar_iswide (gunichar c)
 {
-  if (bsearch (GUINT_TO_POINTER (c),
-               g_unicode_width_table_wide,
-               G_N_ELEMENTS (g_unicode_width_table_wide),
-               sizeof g_unicode_width_table_wide[0],
-              interval_compare))
-    return TRUE;
-
-  return FALSE;
+  if (c < g_unicode_width_table_wide[0].start)
+    return FALSE;
+  else
+    return g_unichar_iswide_bsearch (c);
 }
 
 


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