EM vs Twisted

Omer Katz edited this page Jun 5, 2016 · 3 revisions

I was interested in the performance differences between Twisted and EventMachine for an application I’ve developing which is going to have to handle a lot of load as clients will be regularly polling it.

Disclaimer: I’m fairly new to Python and Twisted – so there may be a way of speeding them up which I’m not aware of – perhaps by compiling to byte code or using a stackless interpreter.

Rather than test performance at a TCP level, I thought I’d do more of a real world example – and test HTTP servers. Thin (combined with Rack) is a HTTP layer to EventMachine. Twisted has its own HTTP parser built in.

Results (recorded with ab)

Concurrency: 20 Requests: 2000

  • EventMachine: Requests per second: 3327.79 #/sec (mean)
  • Twisted: Requests per second: 3194.76 #/sec (mean)

Concurrency: 200 Requests: 20000

  • EventMachine: Requests per second: 4401.80 #/sec (mean)
  • Twisted: Requests per second: 4761.90 #/sec (mean)

Conclusion

Take these tests with a pinch of salt, as the old saying goes something along the lines of ‘There are lies, damned lies, and then there are statistics’.

The results are remarkably similar – with EM beating Twisted at some concurrency levels, and vica versa. There doesn’t seem to be an obvious difference in requests per second – even with an extremely large volume of requests.

To be honest, I’m a bit surprised. Ruby isn’t known for it’s speed, and we’re already using 2 more gems, Thin and Rack which, although they are as light as possible, still add overhead.

When it comes down to virtual memory Ruby uses a hefty 47 mb, but Python isn’t much better at 39 mb. I don’t suppose that would be a deal breaker for most people though.

I call it a draw ;)

Versions

EventMachine 0.10.0
Ruby 1.8.6
Thin 0.7.0
Python 2.5
Twisted 2.5.0

em_test.ru

app = proc do |env|
  [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now.to_i}"]]
end

run app

Run with: thin start —rackup em_test.ru

twisted_test.py

import time
from twisted.internet import protocol, reactor

class TimeProtocol(protocol.Protocol):
    def connectionMade(self):
        self.transport.write(
            'Hello. The time is %s' % time.time())
        self.transport.loseConnection()

class TimeFactory(protocol.ServerFactory):
    protocol = TimeProtocol

reactor.listenTCP(3001, TimeFactory())
reactor.run()

Run with: python twisted_test.py

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.