显示谓词子句的每个目标的执行时间



我想用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而不是runtimeStartStop以毫秒为单位,但上次我将其与 SICStus 一起使用时,它只返回 10 的倍数。在一个项目中,我们使用对自定义外部 C 库的调用来检索更精细的分辨率。

time_out/3的评论:它用于限制目标的运行时间,而不是测量其运行时间。如果目标及时完成,则结果为 success ,如果需要更多时间,则中止执行(内部抛出超时异常),结果为 timeout

我想

补充两个想法:

  1. Prolog允许回溯,因此目标可能会多次成功。

    您感兴趣的"运行时"是什么?

    • 只有计算上一个答案的工作?
    • 或者更确切地说是总时间?
  2. 使用 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时间命令的类似物,因为它是一个接受目标参数的元谓词。比石器时代的方法更好。

最新更新