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.
This commit is contained in:
Matthias Clasen 2015-09-10 23:57:01 -04:00
parent 96675446c5
commit 97a25d1203

View File

@ -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;
if (c < g_unicode_width_table_wide[0].start)
return FALSE;
else
return g_unichar_iswide_bsearch (c);
}