Le 27/04/2014 22:28, Pavel Roschin a écrit :
I found interesting function in utils.c:
gboolean utils_str_equal(const gchar *a, const gchar *b) { [...]
while (*a == *b++) if (*a++ == '\0') return TRUE;
return FALSE; }
This function is widely used in Geany code.
However:
- it is not inline so there is no reason to keep this small while loop
- it uses own while-loop to compare that is *slow* for big strings
- GLib has similar g_strcmp0 function since 2.16
Using while-loop may confuse compiler which knows strcmp and may optimize this std call e.g. for constants. Furthermore strcmp is SSE-accelerated function which compares 128 bits per cycle while this implementstion may compare only 8 bits per cycle.
Ouch indeed. I just replaced the loop with a strcmp(), which performs roughly 5.4 times better (on a 64bits Linux) for dummy average strings. Thanks for spotting this.
Replace this by inline (g_strcmp0(a, b) == 0). This is much faster and easier to read.
Well, the problem is that utils_str_equal() is part of the plugin API, so we can't make it a macro expanding to a non-function without breaking API. Also, I don't think "g_strcmp0(a, b) == 0" is easier to read than "utils_str_equal(a, b)" -- OK strcmp() is obvious, but strcmp0() is not, and utils_str_equal() is quite explicit.
Also, my naive tests showing the strcmp() version being 5.4 times faster (from 22.8301s to 4.22474s) shows very little gain with calling g_strcmp0() (+.02, 42.1628s vs 41.242s) -- and I would think it probably depends on optimization/debug compiler options, since both implementations are very similar (maybe g_strcmp0() is a little better because it does some tests only in some branches, but OTOH the compiler can easily improve our branching to lower test hitting).
Regards, Colomban