私はいくつかのプログラムで遊んでいてpermutation
、この小さな実験に出くわしました:
順列方法 1:
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)).
次の結果が得られました。これは、いくつかの実行で比較的一貫しています。
方法 1:
% 772,064 inferences, 1.112 CPU in 2.378 seconds (47% CPU, 694451 Lips)
方法 2:
% 3,322,118 inferences, 2.126 CPU in 4.660 seconds (46% CPU, 1562923 Lips)
方法 3:
% 2,959,245 inferences, 1.967 CPU in 4.217 seconds (47% CPU, 1504539 Lips)
したがって、非末尾再帰法は、リアルタイム効率が大幅に向上します。
特定の再帰型は、他のすべての条件が等しい場合、一般的にリアルタイムでより効率的ですか (それは必ずしも単純な前提ではないことはわかっています)。この実験が私に教えてくれるのは、常に末尾再帰を求めているわけではなく、最初にパフォーマンス分析を行う必要があるかもしれないということです。次に、末尾再帰が持つ他の利点とパフォーマンスの利点を比較検討してください。