我用b-prolog 8.1 版的表格功能做了一些实验,对 我观察到的性能感到非常惊讶。
这是我使用的代码。它计算将某个正整数减少到所需的Collatz步数:N
I
1
%:- table posInt_CollatzSteps/2. % remove comment to enable tabling
posInt_CollatzSteps(I,N) :-
( I == 1
-> N = 0 % base case
; 1 is I /\ 1
-> I0 is I*3+1, posInt_CollatzSteps(I0,N0), N is N0+1 % odd
; I0 is I>>1, posInt_CollatzSteps(I0,N0), N is N0+1 % even
).
I0
要确定从到的所有整数所需的最大归约步骤数I
:
i0_i_maxSteps0_maxSteps(I0,I,M0,M) :-
( I0 > I
-> M0 = M
; posInt_CollatzSteps(I0,N0),
I1 is I0+1,
M1 is max(M0,N0),
i0_i_maxSteps0_maxSteps(I1,I,M1,M)
).
当我在没有和使用表格的情况下运行一些查询?- time(i0_i_maxSteps0_maxSteps(1,1000000,0,MaxSteps)).
时,我观察到以下运行时(以秒为单位):
- 不带表格:6.784
- 带表:2.323、19.78、3.089、3.084、3.081 _ _ _ _
通过添加:- table posInt_CollatzSteps/2.
查询,速度提高了 2 倍。尽管如此,我还是很困惑:
- 第二次运行比第一次慢 5 倍以上。显然大部分时间都花在了 GC 上。从第 3 次运行开始,制表变体再次变快。
- 热运行(第 3 次、第 4 次、...)明显慢于冷运行(第 1 次)。
我没想到会这样!将此与我在xsb版本 3.6.0 中观察到的运行时进行对比:
- 不带表格:14.287
- 带表:1.829、0.31、0.308、0.31、0.333 _ _ _ _
我能做些什么?是否有任何指令或标志可以帮助我使用 BProlog 获得更好的性能?我在 Linux 上使用 BProlog 版本 8.1 64 位版本。