[glib/faster-contenttype-guess] xdgmime: Use memmem when we can
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/faster-contenttype-guess] xdgmime: Use memmem when we can
- Date: Tue, 15 Oct 2019 15:59:21 +0000 (UTC)
commit 0917506dcf843333301d130a264f5b95052b2171
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Oct 15 11:56:16 2019 -0400
xdgmime: Use memmem when we can
When comparing magic without a mask, we can use
the optimized function that glibc has for this
purpose.
This makes g_content_type_guess drop from 10%
to 3% in some of my GTK profiles. Still not
ideal. It would be much better if we could
ask 'Which of these 3 types is it?' style
questions.
gio/xdgmime/xdgmimecache.c | 55 +++++++++++++++++++---------------------------
1 file changed, 23 insertions(+), 32 deletions(-)
---
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
index 769b57836..3150c1cb3 100644
--- a/gio/xdgmime/xdgmimecache.c
+++ b/gio/xdgmime/xdgmimecache.c
@@ -48,6 +48,10 @@
#include "xdgmimecache.h"
#include "xdgmimeint.h"
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
@@ -175,42 +179,29 @@ cache_magic_matchlet_compare_to_data (XdgMimeCache *cache,
xdg_uint32_t data_length = GET_UINT32 (cache->buffer, offset + 12);
xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16);
xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20);
-
+ int end;
int i, j;
+ const unsigned char *_buffer = cache->buffer;
+ const unsigned char *_data = data;
+
+ if (len < data_length)
+ return FALSE;
- for (i = range_start; i < range_start + range_length; i++)
- {
- int valid_matchlet = TRUE;
-
- if (i + data_length > len)
- return FALSE;
+ if (mask_offset == 0)
+ return memmem (_data + range_start, MIN (range_length + data_length, len), _buffer + data_offset,
data_length) != NULL;
- if (mask_offset)
- {
- for (j = 0; j < data_length; j++)
- {
- if ((((unsigned char *)cache->buffer)[data_offset + j] & ((unsigned char
*)cache->buffer)[mask_offset + j]) !=
- ((((unsigned char *) data)[j + i]) & ((unsigned char *)cache->buffer)[mask_offset + j]))
- {
- valid_matchlet = FALSE;
- break;
- }
- }
- }
- else
- {
- for (j = 0; j < data_length; j++)
- {
- if (((unsigned char *)cache->buffer)[data_offset + j] != ((unsigned char *) data)[j + i])
- {
- valid_matchlet = FALSE;
- break;
- }
- }
+ end = MIN (range_start + range_length, len - data_length);
+
+ for (i = range_start; i < end; i++)
+ {
+ for (j = 0; j < data_length; j++)
+ {
+ if ((_buffer[data_offset + j] & _buffer[mask_offset + j]) !=
+ (_data[i + j] & _buffer[mask_offset + j]))
+ break;
}
-
- if (valid_matchlet)
- return TRUE;
+ if (j == data_length)
+ return TRUE;
}
return FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]