Интересно, почему whoosh работает медленно со следующим кодом. Особенно коммит занимает довольно много времени.
Я пытался использовать limitmb=2048 с модулем записи вместо 128 по умолчанию, но это почти не имеет значения. В соответствии с предложениями я попробовал procs=3 для записи, что делает индексацию немного быстрее, но коммит еще медленнее. Также commit(merge=False) здесь не поможет, так как индекс пуст.
Я получаю такие результаты:
index_documents 12.41 seconds
commit 22.79 seconds
run 35.34 seconds
Что для такой маленькой схемы и примерно 45000 объектов кажется многовато.
Я тестировал с whoosh 2.5.7 и Python 2.7.
Это нормально и я просто слишком многого жду, или я что-то не так делаю?
Я также немного профилировал, и кажется, что whoosh пишет, а затем читает много солений. Кажется, это связано с тем, как обрабатываются транзакции.
from contextlib import contextmanager
from whoosh import fields
from whoosh.analysis import NgramWordAnalyzer
from whoosh.index import create_in
import functools
import itertools
import tempfile
import shutil
import time
def timecall(f):
@functools.wraps(f)
def wrapper(*args, **kw):
start = time.time()
result = f(*args, **kw)
end = time.time()
print "%s %.2f seconds" % (f.__name__, end - start)
return result
return wrapper
def schema():
return fields.Schema(
path=fields.ID(stored=True, unique=True),
text=fields.TEXT(analyzer=NgramWordAnalyzer(2, 4), stored=False, phrase=False))
@contextmanager
def create_index():
directory = tempfile.mkdtemp()
try:
yield create_in(directory, schema())
finally:
shutil.rmtree(directory)
def iter_documents():
for root in ('egg', 'ham', 'spam'):
for i in range(1000, 16000):
yield {
u"path": u"/%s/%s" % (root, i),
u"text": u"%s %s" % (root, i)}
@timecall
def index_documents(writer):
start = time.time()
counter = itertools.count()
for doc in iter_documents():
count = counter.next()
current = time.time()
if (current - start) > 1:
print count
start = current
writer.add_document(**doc)
@timecall
def commit(writer):
writer.commit()
@timecall
def run():
with create_index() as ix:
writer = ix.writer()
index_documents(writer)
commit(writer)
if __name__ == '__main__':
run()