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

问题描述 投票:0回答:3

我想使用 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

如何做到这一点?

我尝试了

time_out(:Goal, +Time, -Result)
中的
library(timeout)
,但收到此错误:

| ?- 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
prolog
3个回答
11
投票

您可以使用

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


5
投票

我想补充两个想法:

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

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

    • 仅计算前一个答案的工作?
    • 或者更确切地说是总时间?
  2. 使用

    statistics/2
    ,但不要直接这样做。 相反,使用像这样的抽象
    call_time/2

示例查询:

?- call_time((排列([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
测量了到目前为止的运行时间。


2
投票

由于没有人提到它,如果您只想显示时间,则 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.

不幸的是,GNU Prolog、SICStus Prolog 等 Prolog 系统不支持它。但它类似于 Unix time 命令,因为它是一个带有目标参数的元谓词。比石器时代的方法更好。

© www.soinside.com 2019 - 2024. All rights reserved.