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

StackOverflow https://stackoverflow.com//questions/12669971

Вопрос

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

Насколько я знаю, ключевые различия между ними заключаются в следующем:

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

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

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

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

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

Это было полезно?

Решение

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

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

Аналогичным образом, libev работает очень быстро.Те же причины.

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

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

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

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

Другие советы

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

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

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

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

С другой стороны, если тест будет имитировать нагрузку «обычного дня» (которая будет варьироваться от одного веб-сайта к другому), но в целом может быть приближен к запросу, случайной паузе, повторению.Чем меньше эта пауза — тем больше трафика мы моделируем.Также клиентская часть теста должна будет имитировать задержку.В Linux это можно сделать с помощью Awesome netem[1], в противном случае — путем установки небольших задержек перед вызовами приема/отправки (что было бы очень сложно, поскольку тесты обычно используют библиотеки более высокого уровня).

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top