Привязки python MongoDB на порядок медленнее, чем java?

Я задал этот же вопрос в списке пользователей mongodb: http://groups.google.com/group/mongodb-user/browse_thread/thread/b3470d6a867cd24

Я надеялся, что кто-то на этом форуме может что-то понять...

Я провел простой эксперимент, сравнивая производительность итерации курсора с использованием python и java, и обнаружил, что реализация python примерно в 10 раз медленнее. Я надеялся, что кто-нибудь может сказать мне, ожидается ли эта разница или я делаю что-то явно неэффективное на стороне python.

Бенчмарк прост: он выполняет запрос, перебирает курсор и проверяет одно и то же поле в каждом документе. В версии для Python я могу проверять около 22 тысяч документов в секунду. В java-версии я могу проверять около 220 тыс. документов в секунду.

Я видел несколько похожих вопросов о производительности python, воспользовался советом и убедился, что использую расширения C:

>>> import pymongo 
>>> pymongo.has_c() 
True 
>>> import bson 
>>> bson.has_c() 
True 

Наконец, я не верю, что расхождение связано с фундаментальными различиями между python и java, по крайней мере, на уровне моего тестового кода. Например, если я храню запрошенные документы в списке Python, я могу очень быстро перебирать этот список. Другими словами, разница объясняется не неэффективным циклом for в Python. Кроме того, я получаю почти идентичную производительность Java и Python при вставке документов.

Вот еще несколько деталей о запросе:

  • Реализации Python и Java используют один и тот же запрос для одной и той же коллекции и выполняются на одном компьютере.
  • Коллекция содержит около 20 миллионов документов.
  • Запрос возвращает около 2 миллионов документов, т. е. я получаю около 10% коллекции.
  • Каждый документ содержит три простых поля: дату и две строки.
  • Запрос индексируется, и время, затраченное на фактический запрос, незначительно как для реализации Python, так и для реализации Java. Итерация курсора учитывает время выполнения.

person Sam    schedule 30.03.2012    source источник
comment
Драйвер Java может считывать весь набор результатов в память, а драйвер python передает результаты в потоковом режиме. Вы можете попробовать установить размер партии в обоих драйверах.   -  person Joshua Martell    schedule 31.03.2012
comment
Можете ли вы опубликовать полный код как для Python, так и для Java? Мы можем посмотреть, смогут ли другие повторить ваши результаты.   -  person Chris W.    schedule 06.06.2012
comment
Просто отметим, что если вы перейдете по ссылке на ветку Google Groups, код будет опубликован (на обоих языках), а также проверен людьми 10gen и проведены дополнительные тесты. Тестирование TL; DR 10gen показало, что Python работает чуть более чем в 2 раза медленнее, чем Java, и некоторые различия в тестировании могут быть связаны с используемой версией Python.   -  person Adam Comerford    schedule 19.07.2012
comment
Не могли бы вы опубликовать эти подробности: ваш тестовый сервер (включая ЦП, ОЗУ и т. д.), а также повторно запустить тесты, показывающие больше информации о времени, чем непосредственно до и после вызова foo() - я думаю, сколько в среднем времени это занимает для Java выполнить одну итерацию цикла while? для python выполнить одну итерацию for doc in curs?   -  person cegfault    schedule 19.07.2012
comment
Было бы очень полезно, если бы вы запустили профилировщик своего кода Python и опубликовали результаты. Это похоже на тугую петлю, с которой CPython обычно справляется довольно плохо. Если вам нужна ссылка на это, обратитесь к docs.python.org/library/profile.html   -  person t.dubrownik    schedule 05.08.2012
comment
Пожалуйста, предоставьте тестовый пример, который я могу выполнить сам, и я посмотрю на него.   -  person h4ck3rm1k3    schedule 17.08.2012


Ответы (1)


Что ж, глядя на ваш пост в группах Google, вот мой 2c:

  1. Python медленнее, чем Java. Поскольку Python не типизирован, его интерпретатор не может выполнять всю «магию» Java JIT, поэтому он всегда будет работать медленнее во время выполнения.

  2. В ветке Google Groups указано, что:

«Большим сюрпризом в результатах стало то, как производительность теста Python ухудшается, когда я вставляю более короткие значения. Во всяком случае, я ожидал обратного. Сравнительно, числа Java практически одинаково для длинных и коротких строк».

Это может ввести в заблуждение из-за асинхронного поведения Mongo при записи. Убедитесь, что вы установили один и тот же параметр Write Concern при запуске этих операций записи в тестах Java и Python (и желательно установить его в SAFE_MODE). Другими словами, если вы специально не устанавливаете какой-либо параметр Write Concern, убедитесь, что значение драйвера по умолчанию одинаково в вариантах Python и Java.

person Shivan Dragon    schedule 19.08.2012