From: Stefano Lattarini Date: Wed, 16 May 2012 12:51:24 +0000 (+0200) Subject: [ng] perf: optimize 'am__strip_suffixes' for speed X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c259affdefcd7857788811f4480727c5202d500c;p=thirdparty%2Fautomake.git [ng] perf: optimize 'am__strip_suffixes' for speed This optimization offers some noticeable performance improvements for packages having a lot of tests and using the Automake-provided parallel testsuite harness; this is due to the fact that the internal automake variable 'am__test_bases' used by it is calculated through a proper call to 'am__strip_suffixes'. More precisely, we have measured the times required to complete null "make all", "make recheck" and "make check AM_LAZY_CHECK=yes" invocations in a package with 5000 tests in the top-level directory and other 5000 tests in a subdirectory. Here are the results, averaged on a several runs: + Before this patch: - "make all" 2.7 seconds - "make recheck" 3.9 seconds - "make check AM_LAZY_CHECK=yes" 15.2 seconds + After this patch: - "make all" 0.4 seconds - "make recheck" 1.7 seconds - "make check AM_LAZY_CHECK=yes" 7.2 seconds + In mainline automake (commit v1.12-75-gd89da9c): - "make all" 0.9 seconds - "make recheck" 3.5 seconds - "make check RECHECK_LOGS=" 14.1 seconds See also previous commit v1.12-233-g0010655 "[ng] check: memoize some internal vars (avoid useless recalculation)" for another (weaker) optimization. The need for this optimization has been suggested by Bob Friesenhahn: * lib/am/header-vars.am (am__strip_suffixes): Rewrite in a way that allows much better performance. (am__private_suffix): New internal variable, used by the new implementation. (am__strip_suffixes): Remove, it's not needed anymore. * t/internals.tap: Adjust. Signed-off-by: Stefano Lattarini --- diff --git a/lib/am/header-vars.am b/lib/am/header-vars.am index 386df1f81..10ff773ab 100644 --- a/lib/am/header-vars.am +++ b/lib/am/header-vars.am @@ -103,25 +103,20 @@ am__uniq = $(strip \ am__memoize = $(or $(am__memoized_value/$1),$(strip \ $(eval am__memoized_value/$1 := $$2))$(am__memoized_value/$1)) -## $(call am__strip_suffixes_0, SUFFIXES, WORD) -## -------------------------------------------- -## Strip any of the SUFFIXES from WORD. Even if WORD terminates with -## several suffixes, only one is stripped: the first one that matches. -am__strip_suffixes_0 = $(strip \ - $(if $(strip $(1)), \ - $(if $(filter %$(firstword $(1)), $(2)), \ - $(patsubst %$(firstword $(1)), %, $(2)), \ - $(call am__strip_suffixes_0, \ - $(call am__strip_firstword, $(1)), $(2))), \ - $(2))) - ## $(call am__strip_suffixes, SUFFIXES, LIST) ## ------------------------------------------ ## Strip any of the SUFFIXES from each of the entries of LIST. Even if an ## entry of LIST terminates with several suffixes, only one is stripped: ## the first one that matches. -am__strip_suffixes = \ - $(foreach am__i,$(2),$(call am__strip_suffixes_0,$(1),$(am__i))) +am__private_suffix = .,;&!@ +am__strip_suffixes = $(strip \ + $(if \ + $(strip $1), \ + $(patsubst %$(am__private_suffix),%, \ + $(call am__strip_suffixes, \ + $(call am__strip_firstword,$1), \ + $(patsubst %$(firstword $1),%$(am__private_suffix),$2))), \ + $2)) ## Some derived variables that have been found to be useful. pkgdatadir = $(datadir)/@PACKAGE@ diff --git a/t/internals.tap b/t/internals.tap index 6d6916603..f6ea954bd 100755 --- a/t/internals.tap +++ b/t/internals.tap @@ -19,7 +19,7 @@ am_create_testdir=empty . ./defs || Exit 1 -plan_ 5 +plan_ 4 cp "$am_amdir"/header-vars.am . \ || fatal_ "fetching makefile fragment headers-vars.am" @@ -74,32 +74,6 @@ test-uniq: test '$(call am__uniq,3 1 1 4 1 4 1 1)' = '3 1 4' test '$(call am__uniq, 1 3 1 )' = '1 3' -.PHONY: test-strip-suffixes0 -test-strip-suffixes0: - test '$(call am__strip_suffixes_0,,)' = '' - test '$(call am__strip_suffixes_0, ,)' = '' - test '$(call am__strip_suffixes_0,, )' = '' - test '$(call am__strip_suffixes_0, , )' = '' - test '$(call am__strip_suffixes_0,x,)' = '' - test '$(call am__strip_suffixes_0,x, )' = '' - test '$(call am__strip_suffixes_0,x y, )' = '' - test '$(call am__strip_suffixes_0,,x)' = 'x' - test '$(call am__strip_suffixes_0, ,x)' = 'x' - test '$(call am__strip_suffixes_0,.c,foo.c)' = 'foo' - test '$(call am__strip_suffixes_0,.c .c++, bar.c++)' = 'bar' - test '$(call am__strip_suffixes_0,.c .c++, bar.cxx)' = 'bar.cxx' - test '$(call am__strip_suffixes_0,x,ax)' = 'a' - test '$(call am__strip_suffixes_0,x,xa)' = 'xa' - test '$(call am__strip_suffixes_0,x,xx)' = 'x' - test '$(call am__strip_suffixes_0,x,xux)' = 'xu' - test '$(call am__strip_suffixes_0, .a .b, x.a.a)' = 'x.a' - test '$(call am__strip_suffixes_0, .a .b, x.a.b)' = 'x.a' - test '$(call am__strip_suffixes_0, .a .b, x.b.a)' = 'x.b' - test '$(call am__strip_suffixes_0, .a .b, x.b.b)' = 'x.b' - # Corner cases: the *first* matched suffix is stripped - test '$(call am__strip_suffixes_0, .a .b.a, foo.b.a)' = 'foo.b' - test '$(call am__strip_suffixes_0, .b.a .a, foo.b.a)' = 'foo' - .PHONY: test-strip-suffixes test-strip-suffixes: test '$(call am__strip_suffixes,,)' = '' @@ -113,21 +87,28 @@ test-strip-suffixes: test '$(call am__strip_suffixes,.c,foo.c)' = 'foo' test '$(call am__strip_suffixes,.foo,a.foo b.foo)' = 'a b' test '$(call am__strip_suffixes, x y, ax ay ax)' = 'a a a' + test '$(call am__strip_suffixes,x,ax)' = 'a' + test '$(call am__strip_suffixes,x,xa)' = 'xa' + test '$(call am__strip_suffixes,x,xx)' = 'x' + test '$(call am__strip_suffixes,x,xux)' = 'xu' test '$(call am__strip_suffixes, .c .c++, \ foo.c bar.c++ baz.cxx zap.c)' = 'foo bar baz.cxx zap' test '$(call am__strip_suffixes, .a .b, \ 1.a.a 2.a.b 3.b.a 4.b.b)' = '1.a 2.a 3.b 4.b' # Corner cases: the *first* matched suffix is stripped + test '$(call am__strip_suffixes,.a .b,x.a.a)' = 'x.a' + test '$(call am__strip_suffixes,.a .b,x.a.b)' = 'x.a' + test '$(call am__strip_suffixes,.a .b,x.b.a)' = 'x.b' + test '$(call am__strip_suffixes,.a .b,x.b.b)' = 'x.b' test '$(call am__strip_suffixes, .a .b.a, foo.b.a bar.a)' \ - = 'foo.b bar' + = 'foo.b bar' test '$(call am__strip_suffixes, .b.a .a, foo.b.a bar.a)' \ - = 'foo bar' + = 'foo bar' END command_ok_ am__strip_firstword $MAKE test-strip-firstword command_ok_ am__strip_lastword $MAKE test-strip-lastword command_ok_ am__uniq $MAKE test-uniq -command_ok_ am__test_strip_suffixes_0 $MAKE test-strip-suffixes0 command_ok_ am__test_strip_suffixes $MAKE test-strip-suffixes :