Почему EventMachine намного медленнее, чем Node? - PullRequest
6 голосов
/ 25 мая 2011

В моем конкретном случае, по крайней мере.Здесь я не пытаюсь делать общие заявления.

У меня есть этот веб-сканер, который я написал в Node.js.Я хотел бы использовать Ruby вместо этого, поэтому я переписал его в EventMachine.Так как оригинал был на CoffeeScript, он был на самом деле удивительно прост, и код во многом такой же, за исключением того, что в EventMachine я могу фактически перехватывать и восстанавливать исключения (поскольку я использую волокна).проблема в том, что тесты, которые выполняются менее чем за 20 секунд в коде Node.js, занимают до 5 минут в EventMachine.Когда я наблюдаю за подсчетом соединений, кажется, что они даже не работают параллельно (они выстраиваются в очередь до сотен, а затем очень медленно идут вниз), хотя регистрация показывает, что кодовые точки достигаютПараллельно.

Я понимаю, что без кода вы не можете точно знать, что именно происходит, но мне было просто интересно, есть ли какая-то принципиальная разница, и я должен отказаться, или они действительно должны бытьЯ могу продолжать работать так же быстро (небольшое замедление - хорошо), и я должен продолжать пытаться выяснить, в чем проблема.

Я сделал следующее, но на самом деле это не оказало никакого влияния:

puts "Running with ulimit: " + EM.set_descriptor_table_size(60000).to_s
EM.set_effective_user('nobody')
EM.kqueue

О, и я очень уверен, что у меня нет никаких блокирующих вызовов в EventMachine.Я пролистал каждую строку около 10 раз, ища что-нибудь, что могло бы блокировать.Все мои сетевые вызовы - EM :: HttpRequest.

1 Ответ

13 голосов
/ 25 мая 2011

Проблема в том, что тесты, которые выполняются менее чем за 20 секунд в коде Node.js, занимают в EventMachine до 5 минут и более.Когда я наблюдаю за подсчетом соединений, кажется, что они даже не работают параллельно (они выстраиваются в очередь до сотен, а затем очень медленно идут вниз), хотя регистрация показывает, что кодовые точки выполняются параллельно.

Если они не работают параллельно, то это не асинхронно.Итак, вы блокируете.

По сути, вам нужно выяснить, какой блокирующий вызов ввода-вывода вы сделали в стандартной библиотеке Ruby, удалить его и заменить его не блокирующим вызовом ввода-вывода EventMachine.

В вашем коде могут отсутствовать какие-либо блокирующие вызовы, но вы используете сторонний код, который не принадлежит вам или нет из EM?Они могут заблокировать.Даже что-то простое, например отладочная печать / журнал, может заблокировать.

Все мои сетевые вызовы - EM :: HttpRequest.

А как насчет файлового ввода-вывода, а как насчет TCP?Как насчет всего, что может заблокировать.Как насчет сторонних библиотек.

Нам действительно нужно увидеть здесь некоторый код.Либо идентифицируйте горлышко бутылки в вашем коде, либо блокирующий вызов.

node.js не должен быть более чем на порядок быстрее, чем EM.

...