public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Speed up fnmatch
@ 2005-03-29 19:17 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2005-03-29 19:17 UTC (permalink / raw)
  To: Ulrich Drepper, Roland McGrath; +Cc: Glibc hackers

Hi!

On the ld testcase
http://sources.redhat.com/ml/binutils/2005-02/msg00375.html
the 4 mbsrtowcs calls in fnmatch show quite high on the profiles.

For small strings I think we can very well have the luxury of allocating
bigger buffers and do just a strnlen instead of one mbsrtowcs call with
NULL first argument to compute the size first and then second mbsrtowcs
call to do the conversion.

With this patch, I get 22% speedup on linking libgklayout.so in en_US.UTF-8
locale.

2005-03-29  Jakub Jelinek  <jakub@redhat.com>

	* posix/fnmatch.c (fnmatch): For short patterns or strings attempt to
	avoid calling mbsrtowcs twice.

--- libc/posix/fnmatch.c.jj	2003-11-19 10:24:00.000000000 +0100
+++ libc/posix/fnmatch.c	2005-03-29 13:53:49.000000000 +0200
@@ -327,31 +327,74 @@ fnmatch (pattern, string, flags)
     {
       mbstate_t ps;
       size_t n;
+      const char *p;
       wchar_t *wpattern;
       wchar_t *wstring;
 
       /* Convert the strings into wide characters.  */
       memset (&ps, '\0', sizeof (ps));
-      n = mbsrtowcs (NULL, &pattern, 0, &ps);
-      if (__builtin_expect (n == (size_t) -1, 0))
-	/* Something wrong.
-	   XXX Do we have to set `errno' to something which mbsrtows hasn't
-	   already done?  */
-	return -1;
-      wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
-      assert (mbsinit (&ps));
-      (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
+      p = pattern;
+#ifdef _LIBC
+      n = strnlen (pattern, 1024);
+#else
+      n = strlen (pattern);
+#endif
+      if (__builtin_expect (n < 1024, 1))
+	{
+	  wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+	  n = mbsrtowcs (wpattern, &p, n + 1, &ps);
+	  if (__builtin_expect (n == (size_t) -1, 0))
+	    /* Something wrong.
+	       XXX Do we have to set `errno' to something which mbsrtows hasn't
+	       already done?  */
+	    return -1;
+	  if (p)
+	    memset (&ps, '\0', sizeof (ps));
+	}
+      if (__builtin_expect (p != NULL, 0))
+	{
+	  n = mbsrtowcs (NULL, &pattern, 0, &ps);
+	  if (__builtin_expect (n == (size_t) -1, 0))
+	    /* Something wrong.
+	       XXX Do we have to set `errno' to something which mbsrtows hasn't
+	       already done?  */
+	    return -1;
+	  wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+	  assert (mbsinit (&ps));
+	  (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
+	}
 
       assert (mbsinit (&ps));
-      n = mbsrtowcs (NULL, &string, 0, &ps);
-      if (__builtin_expect (n == (size_t) -1, 0))
-	/* Something wrong.
-	   XXX Do we have to set `errno' to something which mbsrtows hasn't
-	   already done?  */
-	return -1;
-      wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
-      assert (mbsinit (&ps));
-      (void) mbsrtowcs (wstring, &string, n + 1, &ps);
+#ifdef _LIBC
+      n = strnlen (string, 1024);
+#else
+      n = strlen (string);
+#endif
+      p = string;
+      if (__builtin_expect (n < 1024, 1))
+	{
+	  wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+	  n = mbsrtowcs (wstring, &p, n + 1, &ps);
+	  if (__builtin_expect (n == (size_t) -1, 0))
+	    /* Something wrong.
+	       XXX Do we have to set `errno' to something which mbsrtows hasn't
+	       already done?  */
+	    return -1;
+	  if (p)
+	    memset (&ps, '\0', sizeof (ps));
+	}
+      if (__builtin_expect (p != NULL, 0))
+	{
+	  n = mbsrtowcs (NULL, &string, 0, &ps);
+	  if (__builtin_expect (n == (size_t) -1, 0))
+	    /* Something wrong.
+	       XXX Do we have to set `errno' to something which mbsrtows hasn't
+	       already done?  */
+	    return -1;
+	  wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+	  assert (mbsinit (&ps));
+	  (void) mbsrtowcs (wstring, &string, n + 1, &ps);
+	}
 
       return internal_fnwmatch (wpattern, wstring, wstring + n,
 				flags & FNM_PERIOD, flags);


	Jakub

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-03-29 19:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-29 19:17 [PATCH] Speed up fnmatch Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).