Что делает существенную разницу в производительности между eventlet и gevent? - программирование
Подтвердить что ты не робот

Что делает существенную разницу в производительности между eventlet и gevent?

Эти две библиотеки разделяют аналогичную философию и аналогичные проектные решения в результате. Но этот популярный тест WSGI говорит, что eventlet работает медленнее, чем gevent. Что отличает их производительность?

Как я знаю, ключевые различия между ними:

  • gevent преднамеренно зависит от и libev (libevent, ранее), а eventlet определяет независимый интерфейс реактора и реализует конкретные адаптеры с использованием select, epoll и витой реактор за этим. Имеет ли дополнительный интерфейс реактора критические характеристики?

  • gevent в основном написан в Cython, а eventlet написан на чистом Python. Изначально компилируется Cython так быстро, как чистый Python, для не очень-вычислительных, но IO-связанных программ?

  • Примитивы gevent эмулируют интерфейсы стандартных библиотек, в то время как примитивы eventlet s отличаются от стандартных и предоставляют дополнительный уровень для эмуляции. Повышает ли дополнительный уровень эмуляции eventlet?

  • Является ли реализация eventlet.wsgi хуже, чем gevent.pywsgi?

Мне действительно интересно, потому что они в целом выглядят так похожими для меня.

4b9b3361

Ответ 1

Ну, gevent не "в основном" написан в Cython, хотя некоторые критические разделы.

Cython имеет огромное значение. Оптимизация процессоров работает намного лучше с скомпилированным кодом. Например, предсказание ветки разваливается в системах на базе VM, потому что косвенность ветвления на уровне выполнения VM непрозрачна для него. Отпечаток кеша более жесткий. Скомпилированный код здесь имеет огромное значение, и IO может быть очень чувствительным к задержке.

В аналогичном ключе libev очень быстро. Те же причины.

Кажется, что eventlet не должен был использовать концентратор select (Python 2.6 обычно по умолчанию использует epoll). Если бы он застрял в выборе, тем не менее, это сделало бы его очень медленным (потому что Python должен преобразовывать выбранный fd_set взад и вперед в список Python, поэтому он становится уродливым, когда он находится в середине цикла).

Я не делал профилирования, но я был бы готов поспорить, что libev/libevent plus Cython имеет большое значение. Примечательно, что некоторые из примитивов с резьбой находятся в Cython в gevent. Это большое дело, потому что много кода косвенно косвенно затрагивает их через IO и даже стандартную библиотеку в некоторых местах.

Что касается дополнительного слоя эмуляции eventlet, то, похоже, намного больше bounciness. В gevent путь кода, по-видимому, создает обратные вызовы и позволяет хабу вызвать их. Кажется, что eventlet выполняет большую часть бухгалтерии, которую хаб делает в gevent. Опять же, я не профилировал его. Что касается самки обезьян, они выглядят довольно схожими.

Сервер WSGI является еще одним сложным. Примечательно, что синтаксический анализ заголовков в gevent откладывается до стандартной библиотеки, тогда как они сами реализуют его в eventlet. Не уверен, что это большое влияние или нет, но неудивительно, что там что-то скрывается. Самое главное, что сервер eventlet основан на обеименной версии стандартной библиотеки BaseHTTPServer. Я не могу себе представить, что это очень оптимально. Gevent реализует сервер, который знает эмуляцию.

Ответ 2

Извините за поздний ответ.

В этом тесте есть две основные причины большой разницы в производительности:

  • как указано выше, критические пути gevent сильно оптимизированы.
  • этот тест проводит стресс-тестирование. Это больше не связано с IO, поскольку оно пытается заставить машину запускать как можно больше запросов. И это, где сияет цитонизированный код.

"В реальном мире", что происходит только во время "slashdot" всплесков трафика. Что важно, и нужно быть готовым, но когда это произойдет, вы реагируете, добавляя больше серверов или отключая тяжелые ресурсы ресурса. Я не видел теста, который на самом деле добавляет больше серверов при увеличении нагрузки.

Если, с другой стороны, контрольный образец будет имитировать нагрузку "обычного дня" (которая будет отличаться от одного веб-сайта к другому), но в целом может быть приближена к запросу, случайной паузе, повторению. Чем меньше эта пауза - тем больше мы имитируем трафик. Кроме того, клиентская сторона теста должна будет моделировать задержку. В Linux это можно сделать с помощью awesome netem [1], в противном случае, поставив небольшие задержки перед вызовами recv/send (что было бы очень сложно, потому что тесты обычно используют библиотеки более высокого уровня).

Теперь, если эти условия выполнены, мы фактически будем тестировать проблемы, связанные с IO. Но результаты не были бы слишком ужасными: все кандидаты успешно обслуживали 10, 50 и даже 200 кв. Скучно, правда? Таким образом, мы могли бы измерить распределение задержек, время для обслуживания 99% запросов и т.д. Gevent все равно показал бы лучшие результаты. Но разница вряд ли будет впечатляющей.

[1] Имитировать отложенные и отброшенные пакеты в Linux