使用PyCLIPS时事实加载非常慢,而使用CLIPS时很快
我有一个基于规则的系统,里面有好几十万条事实,但用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
所以第二批2万条事实加载花了14.6秒。而从CLIPS控制台加载同样的事实文件几乎是瞬间完成的。检查不同的N
值后发现,加载时间大约和sqr(N)
成正比(这让处理大量事实变得完全不可用)。
如果我改变操作顺序,在加载事实后再定义规则,情况也没有好转(显然最后的操作总是最慢的)。
有没有人遇到过这个问题?我是不是用错了PyCLIPS?
我正在使用PyCLIPS v1.0.7.348
和CLIPS v6.3
。
1 个回答
2
CLIPS 6.3在处理不同模式之间的变量比较时,使用了哈希技术。这种方法可以大大提高性能,特别是当有很多类似于你例子中的事实和规则时。在之前的CLIPS版本中,每当有一个新的F1事实被添加时,系统会对所有匹配第二个模式的F2事实进行逐个检查(而且每添加一个新的F2事实也会进行类似的检查)。但是在6.3版本中,系统只会对那些哈希到同一个桶里的事实进行检查,这样可以节省很多时间。PyCLIPS网站上的说明提到,它是用CLIPS 6.24编译的,这就解释了性能上的差异。说实话,我不记得6.24和6.3之间有什么显著的API差异,所以可能可以尝试用更新的CLIPS版本重新编译PyCLIPS,以获得性能上的提升。