This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Testing a speedup to libiberty/concat.c


When glibc provides stpcpy, it seems like it's a big win to use it in
lieu of a strlen/memcpy combo.  On x86-linux, this patch speeds up
`concat' by 45%.

I'd like to get some testing on other systems.  On platforms whose
libc doesn't provide stpcpy, this patch should have no effect.  If
your libc does provide it, please apply the hunk to main, time it,
then apply the other stuff and see what effect it has.  Adjust
MAX_ITER so that it runs in about 20-30 seconds for a good test.
(Careful, you may run out of memory, but I felt it important to
isolate `concat' from `free'.)

You'll need to compile concat.c with "-O2 -DMAIN" and link it with
libiberty.a to get a working executable.

		Thanks,
		--Kaveh


diff -rup orig/egcc-CVS20030721/libiberty/concat.c egcc-CVS20030721/libiberty/concat.c
--- orig/egcc-CVS20030721/libiberty/concat.c	2001-10-17 17:15:40.000000000 -0400
+++ egcc-CVS20030721/libiberty/concat.c	2003-07-21 23:51:06.826169387 -0400
@@ -57,17 +57,10 @@ NOTES
 #include <varargs.h>
 #endif
 
-# if HAVE_STRING_H
-#  include <string.h>
-# else
-#  if HAVE_STRINGS_H
-#   include <strings.h>
-#  endif
-# endif
-
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
+PTR memcpy PARAMS ((void *, const void *, size_t));
+char *stpcpy PARAMS ((char *, const char *));
+size_t strlen PARAMS ((const char*));
+void free PARAMS ((void *));
 
 static inline unsigned long vconcat_length PARAMS ((const char *, va_list));
 static inline unsigned long
@@ -95,11 +88,19 @@ vconcat_copy (dst, first, args)
   const char *arg;
 
   for (arg = first; arg ; arg = va_arg (args, const char *))
+    /* We check HAVE_STPCPY because stpcpy is only faster if the
+       system provides it.  We don't want to use the libiberty version
+       because it's the same as the inline implementation below but
+       with the additional overhead of a function call.  */
+#ifdef HAVE_STPCPY
+    end = stpcpy (end, arg);
+#else
     {
       unsigned long length = strlen (arg);
       memcpy (end, arg, length);
       end += length;
     }
+#endif
   *end = '\000';
 
   return dst;




diff -rup orig/egcc-CVS20030721/libiberty/concat.c egcc-CVS20030721/libiberty/concat.c
--- orig/egcc-CVS20030721/libiberty/concat.c	2001-10-17 17:15:40.000000000 -0400
+++ egcc-CVS20030721/libiberty/concat.c	2003-07-21 23:51:06.826169387 -0400
@@ -223,13 +224,18 @@ reconcat VPARAMS ((char *optr, const cha
 int
 main ()
 {
-  printf ("\"\" = \"%s\"\n", concat (NULLP));
-  printf ("\"a\" = \"%s\"\n", concat ("a", NULLP));
-  printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP));
-  printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP));
-  printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP));
-  printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP));
-  printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP));
+#define MAX_ITER 1000000  
+  unsigned int i;
+  for (i=0; i<MAX_ITER; i++){
+    
+    concat (NULLP);
+    concat ("a", NULLP);
+    concat ("a", "b", NULLP);
+    concat ("a", "b", "c", NULLP);
+    concat ("ab", "cd", NULLP);
+    concat ("ab", "c", "de", NULLP);
+    concat ("", "a", "", "bcd", "ef", NULLP);
+  }
   return 0;
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]