我在玩permutation
几个程序时偶然发现了这个小实验:
排列方法一:
permute([], []).
permute([X|Rest], L) :-
permute(Rest, L1),
select(X, L, L1).
排列方法2:
permute([], []).
permute(L, [P | P1]) :-
select(P, L, L1),
permute(L1, P1).
排列方法3(使用内置):
permute(L, P) :- permutation(L, P).
我知道使用尾递归是一种很好的做法,并且通常使用内置函数应该是有效的。但是当我运行以下命令时:
time(findall(P, permute([1,2,3,4,5,6,7,8,9], P), L)).
我得到了以下结果,这些结果在多次运行中相对一致:
方法一:
% 772,064 inferences, 1.112 CPU in 2.378 seconds (47% CPU, 694451 Lips)
方法二:
% 3,322,118 inferences, 2.126 CPU in 4.660 seconds (46% CPU, 1562923 Lips)
方法三:
% 2,959,245 inferences, 1.967 CPU in 4.217 seconds (47% CPU, 1504539 Lips)
因此,非尾递归方法的实时效率要高得多。
在所有其他条件相同的情况下,特定的递归类型通常是否更实时有效(我知道这并不总是一个简单的前提)?这个实验告诉我的是,我可能不想一直追求尾递归,但我可能需要先进行性能分析,然后权衡性能优势与尾递归确实具有的其他优势。