我想用SICStus Prolog查看谓词目标内的执行时间。
例:
pred :-
goal1,
time,
goal2,
time.
go :-
call(pred).
time_go :-
go,
times(go).
预期成果:
?- time_go.
times_go = 1000ms ,
times_go_goal1 = 500ms,
times_go_goal2 = 500ms
怎么办呢?
我尝试从library(timeout)
time_out(:Goal, +Time, -Result)
,但出现此错误:
| ?- time_out(char_code(a,N), T, Res).
! Instantiation error in argument 2 of user:time_out/3
! goal: time_out(user:char_code(a,_193),_179,_181)
| ?- time_out(char_code(a,N), 1000, Res).
N = 97,
Res = success ? ; % Res=timeout in other example
您可以使用statistics/2
:
statistics(runtime,[Start|_]),
do_something,
statistics(runtime,[Stop|_]),
Runtime is Stop - Start.
或者,如果要包括垃圾回收时间,可以使用total_runtime
而不是runtime
。 Start
和Stop
以毫秒为单位,但上次我将其与 SICStus 一起使用时,它只返回 10 的倍数。在一个项目中,我们使用对自定义外部 C 库的调用来检索更精细的分辨率。
对time_out/3
的评论:它用于限制目标的运行时间,而不是测量其运行时间。如果目标及时完成,则结果为 success
,如果需要更多时间,则中止执行(内部抛出超时异常),结果为 timeout
。
补充两个想法:
Prolog允许回溯,因此目标可能会多次成功。
您感兴趣的"运行时"是什么?
- 只有计算上一个答案的工作?
- 或者更确切地说是总时间?
使用
statistics/2
,但不要直接执行此操作。相反,请使用类似call_time/2
.
示例查询:
?- call_time((permutation([a,b,c,d,e,f,g,h,i],Xs),Xs=[_,_,g,f,e,d,c,b,a]),T_ms)。 Xs = [h, i, g, f, e, d, c, b, a], T_ms = 304; Xs = [i, h, g, f, e, d, c, b, a], T_ms = 345; 假。
请注意,call_time/2
成功两次,T_ms
测量到目前为止的总运行时间。
由于没有人提到它,如果你只想要一个时间显示,time/1 谓词也很有用。它已经被几个Prolog系统支持,如SWI-Prolog,Jekejeke Prolog,O-Prolog等:
Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.19)
?- time((between(1,10000000,_), fail; true)).
% 10,000,001 inferences, 0.453 CPU in 0.468 seconds (97% CPU, 22068968 Lips)
true.
不幸的是,Prolog系统,如GNU Prolog,SICStus Prolog不支持它。但它是Unix时间命令的类似物,因为它是一个接受目标参数的元谓词。比石器时代的方法更好。