This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Testing a speedup to libiberty/concat.c
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org, gcc at gcc dot gnu dot org
- Date: Tue, 22 Jul 2003 11:40:21 -0400 (EDT)
- Subject: 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;
}