Hi Stepan, * Stepan Kasal wrote on Tue, May 23, 2006 at 10:43:50PM CEST: > On Tue, May 23, 2006 at 09:31:18PM +0200, Ralf Wildenhues wrote: > > > I think we can kill the per-file forks before the mkdir_p, too. > > You mean the $(srcdir) and $(top_srcdir) stripping. But it takes > place only in certain situations: > - if the make implementation inserts $(srcdir) (GNU make doesn't)
Right. > - or if the author of Makefile.am usees $(srcdir) or $(top_srcdir) > (well educated maintainers don't) This is wrong. Well-educated maintainers do this in some situations: when the file in question is also listed as prerequisite somewhere (and even $(EXTRA_DIST) is listed as prerequisite somewhere), so that stuff *really* works with non-GNU make. In fact, typical Makefiles generated by Automake contain at least one such file: $(srcdir)/Makefile.in. > So when you replaced all the per-file forks by a constant number of > three forks, you actually slowed down the most common usecase. Even if that were a common case, that would not be clear (it's not clear 3 forks and a sed script are worse that a bunch of shell matching). But it's best not to rely on intuition when optimizing, so here we go (`\time make distdir' of the Automake package itself, on GNU/Linux): before: 3.33user 1.44system 0:05.46elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+740075minor)pagefaults 0swaps your patch: 1.79user 0.58system 0:03.36elapsed 70%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+238784minor)pagefaults 0swaps my patch: 0.65user 0.56system 0:01.87elapsed 65%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+211732minor)pagefaults 0swaps > I think it should be either reverted, or wrapped in a case command, > see below. I haven't applied anything here; it is Alexandre's decision to apply (or tell me to decide). > Moreover, your sed program is not portable; you cannot use semicolon > after the `t' command nor after the `:' command. Right, thanks for catching. > What about the following (quick untested sketch): Some comments inline: > > + list='$(DISTFILES)'; \ > > +## The `case' command eliminates unnecesary forks in most of the cases > > +## when $list would stay intact. > > + case $$list in $(srcdir)/*|$(top_srcdir)/*) \ (trivial omissiong of two leading `*') > > + list=`for file in $$list; do echo $$file; done | \ > > + | sed -e "s|^$$srcdirstrip/||;t" \ > > + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`;; \ > > +## (The second `t' command clears the flag for the next round.) This comment and the sed script isn't right: the second `t' won't be visited if the first one hit. > > + esac; \ > > +## > > +## Make the subdirectories for the files. > > +## (The DISTDIRS list can be incomplete, because files in subdirectories > > can > > +## be specified for `dist' conditionally.) > > +## > > + case $$list in */*) \ > > + ( cd "$(distdir)"; \ At this point, $list is not guaranteed to be newline-separated now. > > + $(mkdir_p) `echo "$$list" | sed -n 's,/[^/]*$$,,p' | sort -u`; \ > > + ) ;; \ > > + esac; \ > > +## > > +## > > + for file in $$list; do \ Cheers, Ralf