Загрузка фактов очень медленно с 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, чтобы получить улучшения производительности.

Другие вопросы по тегам