我有一个基于规则的系统,它包含了几个事实,而且仅仅因为加载事实,我在PyCLIPS上的性能非常差。
我将其缩小到一个简单的示例,其中包含两个模板和一个连接它们的规则(而不执行其他操作):
import clips
import timeit
env = clips.Environment()
env.BuildTemplate('F1', '(slot x (type INTEGER))')
env.BuildTemplate('F2', '(slot x (type INTEGER))')
env.BuildRule('Rule1', '(F1 (x ?val)) (F2 (x ?val))', '')
N = 20000
with open('F1.txt', 'w') as f1:
with open('F2.txt', 'w') as f2:
for n in xrange(N):
print >>f1, '(F1 (x {}))'.format(n)
print >>f2, '(F2 (x {}))'.format(n)
print timeit.timeit(lambda : env.LoadFacts('F1.txt'), number=1)
print timeit.timeit(lambda : env.LoadFacts('F2.txt'), number=1)输出:
0.0951321125031
14.6272768974因此,第二批20K事实需要14.6秒才能加载。从剪辑控制台加载相同的事实文件是即时的。检查N的不同值可以发现,加载时间与sqr(N)大致成正比(使得这在大量事实中完全不可用)。
切换操作的顺序,并在加载事实之后定义规则并不能使事情变得更好(显然,最后的操作总是慢的)。
有人熟悉这个问题吗?我是不是用错了PyCLIPS?
我正在运行PyCLIPS v1.0.7.348和CLIPS v6.3。
发布于 2014-06-29 17:53:28
CLIPS 6.3在联接中使用散列来比较变量从一种模式到另一种模式。当有大量类似于您示例中的事实和规则时,这可以大大提高性能。在以前版本的CLIPS中,当断言一个新的F1事实时,将对所有匹配第二个模式的F2事实进行迭代(对于每个新的F2事实都会发生类似的迭代)。在版本6.3中,迭代只发生在散列到同一个桶中的事实上,其值为?val。PyCLIPS网站上的自述文件页面表明它是用CLIPS 6.24编译的,因此这将解释性能上的差异。我不记得6.24和6.3之间有什么明显的API差异,所以也许可以用较新版本的CLIPS重新编译PyCLIPS以获得性能改进。
https://stackoverflow.com/questions/24476314
复制相似问题