Загрузка фактов очень медленно с PyCLIPS, а быстрая с CLIPS
У меня есть система, основанная на правилах, с несколькими 100 тысячами фактов, и я получаю очень низкую производительность с 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
Таким образом, вторая партия из 20 тысяч фактов загружается за 14,6 секунды. Загрузка тех же файлов фактов из консоли CLIPS происходит мгновенно. Проверка разных значений N
показывает, что время загрузки примерно пропорционально sqr(N)
(делая это совершенно непригодным для большого количества фактов).
Смена порядка операций и определение правила после загрузки фактов не улучшают ситуацию (очевидно, что последняя операция всегда медленная).
Кто-нибудь знаком с этой проблемой? Я неправильно использую PyCLIPS?
я бегу PyCLIPS v1.0.7.348
а также CLIPS v6.3
,
1 ответ
CLIPS 6.3 использует хеширование в соединениях, которые сравнивают переменные из одного шаблона в другой. Это может значительно улучшить производительность, если в вашем примере есть большое количество фактов и правил, аналогичных приведенным в вашем примере. В предыдущих версиях CLIPS, когда утверждается новый факт F1, итерация будет происходить по всем фактам F2, соответствующим второму шаблону (и аналогичная итерация будет происходить для каждого нового факта F2). В версии 6.3 итерация происходит только для фактов, хэшированных в одно и то же место для значения? Val. Страница Readme на веб-сайте PyCLIPS указывает, что она скомпилирована с CLIPS 6.24, поэтому это объясняет разницу в производительности. Впрочем, я не припоминаю каких-либо существенных различий API между 6.24 и 6.3, поэтому может быть возможно перекомпилировать PyCLIPS с более новой версией CLIPS, чтобы получить улучшения производительности.