我有一个基于规则的系统,有几个100k的事实,我得到了非常糟糕的性能与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)
输出:
^{pr2}$所以第二批20K事实需要14.6秒来加载。从CLIPS控制台加载相同的事实文件是即时的。检查N
的不同值会发现加载时间大致与sqr(N)
成正比(这使得这对于大量事实是完全不可用的)。在
切换操作顺序,在加载事实之后定义规则并不能使事情变得更好(显然最后一个操作总是慢操作)。在
有人熟悉这个问题吗?我是不是用错了PyCLIPS?在
我正在运行PyCLIPS v1.0.7.348
和{
CLIPS 6.3在连接中使用散列来比较从一个模式到另一个模式的变量。当有大量事实和规则与您的示例中的事实和规则相似时,这可以显著提高性能。在CLIPS的早期版本中,当断言一个新的F1事实时,迭代将发生在与第二个模式匹配的所有F2事实上(并且每个新的F2事实都会发生类似的迭代)。在版本6.3中,迭代只发生在散列到同一个bucket中的值为?PyCLIPS网站上的Readme页面表明它是用CLIPS 6.24编译的,所以这可以解释性能上的差异。我不记得6.24和6.3之间有什么明显的API差异,所以可以用更新版本的CLIPS重新编译PyCLIPS,以提高性能。在
相关问题 更多 >
编程相关推荐