From f57d328369def0dc728f01918e2b99e2dc2968cb Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 17 Nov 2014 01:31:58 -0500 Subject: Makefile: memoize the spec2 and file2 functions (for performance) --- Makefile | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5fd9bdf..119d07f 100644 --- a/Makefile +++ b/Makefile @@ -20,15 +20,44 @@ WGET = wget all: package +# memoization ################################################################## + +# How to use: Define 2 variables (the type you would pass to $(call): +# `_NAME_main` and `_NAME_hash`. Now, `_NAME_main` is the function getting +# memoized, and _NAME_hash is a function that hashes the function arguments +# into a string suitable for a variable name. +# +# Then, define the final function like: +# +# NAME = $(foreach func,NAME,$(memoized)) + +_main = $(_$(func)_main) +_hash = _memoized_$(_$(func)_hash) +memoized = $(if $($(_hash)),,$(eval $(_hash) := _ $(_main)))$(wordlist 2,$(words $($(_hash))),$($(_hash))) + # utilities #################################################################### # murl = "mangled url" # spec = type|url|extra # file = type/murl/extra # base = type/murl -name2 = $(call spec2,$1,$(foreach package,$2,$($(package)))) -spec2 = $(shell utils/spec2 $1 $(foreach a,$2,'$a')) -file2 = $(shell utils/file2 $1 $(foreach a,$2,'$a')) + +_spec2_main = $(shell utils/spec2 $1 '$2') +_file2_main = $(shell utils/file2 $1 '$2') + +_spec2_hash = spec2$1_$(subst :,^3A,$(subst ^,^5E,$2)) +_file2_hash = file2$1_$2 + +# There's another level of indirection, because $2 is a list, and each item +# needs to be memoized separately +_spec2_memo = $(foreach func,spec2,$(memoized)) +_file2_memo = $(foreach func,file2,$(memoized)) + +name2 = $(call spec2,$1,$(foreach name,$2,$($(name)))) +#spec2 = $(shell utils/spec2 $1 $(foreach a,$2,'$a')) +#file2 = $(shell utils/file2 $1 $(foreach a,$2,'$a')) +spec2 = $(foreach spec,$2,$(call _spec2_memo,$1,$(spec))) +file2 = $(foreach file,$2,$(call _file2_memo,$1,$(file))) specs_for = $(strip $(foreach t,$1,$(filter $t|%,$(if $2,$2,$(specs))))) -- cgit v1.2.3