什么使eventlet和gevent之间的性能有显着差异?

min*_*hee 17 performance wsgi asyncsocket gevent eventlet

这两个库共享相似的哲学和类似的设计决策.但是这个流行的WSGI基准测试表明eventlet速度比慢gevent.是什么让他们的表现如此不同?

据我所知,它们之间的主要区别是:

  • gevent故意取决于和被耦合到libev(libevent先前)而eventlet定义独立反应器接口并实现使用特定的适配器select,epoll和它后面扭曲反应器中.额外的反应器接口是否会产生关键性能?

  • gevent主要用Cython编写,而eventlet用纯Python编写.本机编译Cython比纯Python更快,对于计算量不大但是IO绑定的程序?

  • 的原语gevent仿效标准库接口而eventlet的基元从标准不同,并提供额外的层来模拟它.额外的仿真层是否会eventlet变慢?

  • 执行eventlet.wsgi情况比刚好差gevent.pywsgi吗?

我真的很好奇,因为它们对我来说总体看起来很相似.

小智 12

好吧,gevent不是"大部分"用Cython编写的,尽管有些关键部分是.

Cython带来了巨大的变化.使用编译代码可以更好地处理器优化.例如,分支预测在基于VM的系统中崩溃,因为VM执行级别的分支的间接对它是不透明的.缓存占用空间更小.编译代码在这里产生巨大的差异,IO可能对延迟非常敏感.

同样,libev非常快.原因相同.

似乎eventlet不应该使用select hub(Python 2.6通常默认为epoll).如果它被卡在select上,那么这会让它变得非常慢(因为Python必须将select fd_set来回转换为Python列表,所以当它处于循环中时会变得很丑陋).

我没有做过任何分析,但我愿意打赌libev/libevent加上Cython会产生很大的不同.值得注意的是,一些线程原语在gevent中的Cython中.这是一个大问题,因为许多代码通过IO间接触及它们,甚至在某些地方甚至是标准库.

至于eventlet的附加仿真层,似乎确实有更多的弹性.在gevent中,代码路径似乎构造了回调并让集线器调用它们.eventlet似乎做了更多的集线器在gevent中进行的簿记.尽管如此,我还没有对它进行分析.至于monkeypatching本身,它们看起来非常相似.

WSGI服务器是另一个困难的服务器.值得注意的是,gevent中的头解析被推迟到标准库,而他们自己在eventlet中实现它.不确定这是否会产生重大影响,但如果有潜伏的东西就不足为奇了.最有说服力的是,eventlet的服务器基于标准库BaseHTTPServer的monkeypatched版本.我无法想象这是非常理想的.Gevent实现了一个知道仿真的服务器.