如何多次连续运行Prolog程序以获取精确运行时?
解决Prolog程序多次运行统计时间的方案
你遇到的time/1精度不足的问题很常见,尤其是当程序运行时间很短的时候。通过多次运行取平均的思路完全可行,下面我给你具体实现方法:
核心思路
我们可以用递归谓词重复执行目标程序,结合高精度的计时函数记录总耗时,最后除以运行次数得到单次平均时间。相比time/1,get_time/1(或statistics/2)能提供带小数的时间戳,精度足够支撑你的需求。
实现代码示例
基础版:基于墙上时间的统计
这个版本使用系统的墙上时间(从某个固定点到现在的时间)来计算耗时:
% 基础情况:运行0次时总耗时为0 run_n_times(0, _, 0.0). % 递归执行N次目标,累加总耗时 run_n_times(N, Goal, TotalTime) :- N > 0, get_time(Start), % 获取运行前的时间戳 call(Goal), % 执行你的目标程序 get_time(End), % 获取运行后的时间戳 TimeTaken is End - Start, % 计算单次耗时 N1 is N - 1, run_n_times(N1, Goal, RestTime), % 递归执行剩下的N-1次 TotalTime is TimeTaken + RestTime. % 累加总耗时 % 计算单次平均运行时间的封装谓词 average_run_time(N, Goal, AvgTime) :- run_n_times(N, Goal, Total), AvgTime is Total / N.
进阶版:基于CPU时间的统计
如果想排除系统其他进程的干扰,统计程序实际占用的CPU时间,可以用statistics/2(以SWI-Prolog为例):
run_n_times(0, _, 0.0). run_n_times(N, Goal, TotalCPUTime) :- N > 0, statistics(cpu_time, [Start|_]), % 获取CPU时间起始值 call(Goal), statistics(cpu_time, [End|_]), % 获取CPU时间结束值 TimeTaken is End - Start, N1 is N - 1, run_n_times(N1, Goal, RestTime), TotalCPUTime is TimeTaken + RestTime. average_run_time(N, Goal, AvgCPUTime) :- run_n_times(N, Goal, Total), AvgCPUTime is Total / N.
使用方法
假设你的目标程序是my_program,要运行1000次统计平均时间,直接在Prolog控制台调用:
average_run_time(1000, my_program, AvgTime).
执行完成后,AvgTime变量就会存储单次运行的平均时间(单位:秒)。
注意事项
- 清理运行残留:如果你的程序会修改Prolog数据库(比如用
assert添加事实),一定要在每次运行后清理状态,避免影响后续执行。比如在call(Goal)之后添加retractall(your_fact(_))来删除相关事实。 - 调整运行次数:如果1000次的结果还是不够稳定,可以适当增加次数(比如10000次),提升平均时间的精度。
- 适配Prolog实现:不同Prolog方言的计时函数可能略有差异,比如有些方言用
current_time/1代替get_time/1,可以根据你使用的版本调整。
内容的提问来源于stack exchange,提问作者Toby Cannon
相关产品推荐
相关产品推荐

