简体   繁体   English

为什么 EventMachine 比 Node 慢这么多?

[英]Why is EventMachine so much slower than Node?

In my specific case, at least.至少在我的具体情况下。 Not trying to make general statements here.此处不作一般性陈述。

I've got this web crawler that I wrote in Node.js.我有我在 Node.js 中编写的这个 web 爬虫。 I'd love to use Ruby instead, so I re-wrote it in EventMachine.我很想改用 Ruby,所以我在 EventMachine 中重新编写了它。 Since the original was in CoffeeScript, it was actually surprisingly easy, and the code is very much the same, except that in EventMachine I can actually trap and recover from exceptions (since I'm using fibers).由于原始文件在 CoffeeScript 中,因此它实际上非常简单,而且代码非常相似,除了在 EventMachine 中我实际上可以捕获异常并从异常中恢复(因为我使用的是光纤)。

The problem is that tests that run in under 20 seconds on the Node.js code take up to and over 5 minutes on EventMachine.问题在于,在 Node.js 代码上运行不到 20 秒的测试在 EventMachine 上需要长达 5 分钟或超过 5 分钟。 When I watch the connection count it almost looks like they are not even running in parallel (they queue up into the hundreds, then very slowly work their way down), though logging shows that the code points are hit in parallel.当我观察连接计数时,它们几乎看起来甚至没有并行运行(它们排队成数百个,然后非常缓慢地向下工作),尽管日志记录显示代码点并行命中的。

I realize that without code you can't really know what exactly is going on, but I was just wondering if there is some kind of underlying difference and I should give up, or if they really should be able to run about as fast (a small slowdown is fine) and I should keep trying to figure out what the issue is.我意识到没有代码你不能真正知道到底发生了什么,但我只是想知道是否存在某种潜在的差异,我应该放弃,或者他们是否真的应该能够以同样快的速度运行(a小幅减速很好),我应该继续努力找出问题所在。

I did the following, but it didn't really seem to have any effect:我做了以下,但它似乎并没有真正产生任何影响:

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

Oh, and I'm very sure that I don't have any blocking calls in EventMachine.哦,我确定我在 EventMachine 中没有任何阻塞调用。 I've combed through every line about 10 times looking for anything that could be blocking.我已经对每一行进行了大约 10 次梳理,寻找任何可能阻塞的内容。 All my network calls are EM::HttpRequest.我所有的网络调用都是 EM::HttpRequest。

The problem is that tests that run in under 20 seconds on the Node.js code take up to and over 5 minutes on EventMachine.问题在于,在 Node.js 代码上运行不到 20 秒的测试在 EventMachine 上需要长达 5 分钟或超过 5 分钟。 When I watch the connection count it almost looks like they are not even running in parallel (they queue up into the hundreds, then very slowly work their way down), though logging shows that the code points are hit in parallel.当我观察连接计数时,它们几乎看起来甚至没有并行运行(它们排队成数百个,然后非常缓慢地向下工作),尽管日志记录显示代码点是并行命中的。

If they're not running in parallel then it's not asynchronous.如果它们没有并行运行,那么它就不是异步的。 So you're blocking.所以你在阻止。

Basically you need to figure out what blocking IO call you've made in the standard Ruby library and remove that and replace it with an EventMachine non blocking IO call.基本上,您需要弄清楚您在标准 Ruby 库中所做的阻塞 IO 调用,并将其删除并替换为 EventMachine 非阻塞 IO 调用。

Your code may not have any blocking calls but are you using 3rd party code that is not your own or not from EM ?您的代码可能没有任何阻塞调用,但您使用的不是您自己的或不是来自EM的第 3 方代码? They may block.他们可能会阻止。 Even something as simple as a debug print / log can block.即使是像调试打印/日志这样简单的东西也可能会阻塞。

All my network calls are EM::HttpRequest.我所有的网络调用都是 EM::HttpRequest。

What about file IO, what about TCP?文件 IO 怎么样,TCP 怎么样? What about anything else that can block.其他可以阻止的东西呢。 What about 3rd party libraries.第三方库呢。

We really need to see some code here.我们真的需要在这里看到一些代码。 Either to identify a bottle neck in your code or a blocking call.识别代码中的瓶颈或阻塞调用。

node.js should not be more than an order of magnitude faster then EM. node.js 不应比 EM 快一个数量级以上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM