gpt4 book ai didi

optimization - Logtalk方法调用性能优化

转载 作者:行者123 更新时间:2023-12-03 17:12:14 25 4
gpt4 key购买 nike

在使用 Logtalk 时,我的程序似乎使用 Logtalk 对象执行的时间比普通 Prolog 的执行时间要长。我做了一个基准测试,将普通 Prolog 中的简单谓词的执行与下面等效的 logtalk 对象封装进行比较:

%%
% plain prolog predicate
plain_prolog_simple :-
fail.

%%
% object encapsulation
:- object(logtalk_obj).

:- public([simple/0]).
simple :-
fail.

:- end_object.

这是我得到的:

?- benchmark(plain_prolog_simple).

Number of repetitions: 500000
Total time calls: 0.33799099922180176 seconds
Average time per call: 6.759819984436035e-7 seconds
Number of calls per second: 1479329.3346604244
true.

?- benchmark(logtalk_obj::simple).

Number of repetitions: 500000
Total time calls: 2.950408935546875 seconds
Average time per call: 5.90081787109375e-6 seconds
Number of calls per second: 169468.0333888435
true.

我们可以看到 logtalk_obj::simple 调用plain_prolog_simple 调用慢。我使用SWI Prolog作为后端,我尝试设置一些日志谈话标志,但没有成功。

编辑:我们可以找到 https://github.com/koryonik/logtalk-experiments/tree/master/benchmarks 的基准代码示例

怎么了?为什么会出现这种性能差异?如何优化Logtalk方法调用?

最佳答案

简而言之,您正在顶级解释器上对 ::/2 目标的 Logtalk 编译进行基准测试。这是一个典型的基准测试错误。顶层的目标,无论是普通的 Prolog 目标、模块显式限定谓词目标还是消息发送目标,总是会被解释,即动态编译。

对于编译源文件中的消息发送目标,您可以获得接近普通 Prolog 的性能,这是最常见的情况。请参阅 Logtalk 发行版中的基准测试示例,了解避免上述陷阱的基准测试解决方案。

性能差距(普通 Prolog 和 Logtalk 目标之间)取决于所选的后端 Prolog 编译器。当可以进行静态绑定(bind)时,对于成熟的 Prolog VM(例如 SICStus Prolog 或 ECLiPSe),该差距可以忽略不计。然而,一些 Prolog VM(例如 SWI-Prolog)缺乏一些可以使差距更大的优化,特别是在紧密循环中。

附注Logtalk 开箱即用,带有用于开发的设置配置,而不是用于性能的设置配置。请特别参阅有关 optimize 标志的文档,应打开该标志以进行静态绑定(bind)优化。

更新

从存储库中的代码开始,假设 SWI-Prolog 作为后端编译器,请尝试:

----- code.lgt -----
% plain prolog predicate
plain_prolog_simple :-
fail.

% object encapsulation
:- object(logtalk_obj).

:- public(simple/0).
simple :-
fail.

:- end_object.
--------------------

----- bench.lgt -----
% load the SWI-Prolog "statistics" library
:- use_module(library(statistics)).

:- object(bench).

:- public(bench/0).
bench :-
write('Plain Prolog goal:'), nl,
prolog_statistics:time({plain_prolog_simple}).
bench :-
write('Logtalk goal:'), nl,
prolog_statistics:time(logtalk_obj::simple).
bench.

:- end_object.
---------------------

保存这两个文件,然后启动 Logtalk:

$ swilgt
...
?- set_logtalk_flag(optimize, on).
true.

?- {code, bench}.
% [ /Users/pmoura/Desktop/bench/code.lgt loaded ]
% (0 warnings)
% [ /Users/pmoura/Desktop/bench/bench.lgt loaded ]
% (0 warnings)
true.

?- bench::bench.
Plain Prolog goal:
% 2 inferences, 0.000 CPU in 0.000 seconds (69% CPU, 125000 Lips)
Logtalk goal:
% 2 inferences, 0.000 CPU in 0.000 seconds (70% CPU, 285714 Lips)
true.

time/1 谓词是一个元谓词。 Logtalk 编译器使用元谓词属性来编译 time/1 参数。 {}/1 控制构造是 Logtalk 编译器旁路。它确保其参数在普通 Prolog 数据库中按原样调用。

关于optimization - Logtalk方法调用性能优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32799458/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com