Pergunta

This is my test case, I found that the EM is not faster than the general TCP server

the EM server:

    require 'rubygems'
    require 'benchmark'
    require 'eventmachine'
    class Handler  < EventMachine::Connection
      def receive_data(data)
            operation = proc do
                # simulate a long running request
                 a = []
                n = 5000
                for i in 1..n
                    a << rand(n)
                    a.sort!
                end
            end

        # Callback block to execute once the request is fulfilled
        callback = proc do |res|
            send_data "send_response\n"
        end

            puts data
            EM.defer(operation, callback)
      end
    end

    EventMachine::run {
      EventMachine.epoll
      EventMachine::start_server("0.0.0.0", 8080, Handler)
      puts "Listening..."
    }

and my benchmark test:

require 'rubygems'
require 'benchmark'
require 'socket'
Benchmark.bm do |x|
    x.report("times:") do
        for i in 1..20
            TCPSocket.open "127.0.0.1", 8080 do |s|
                    s.send "#{i}th sending\n", 0    
                if line = s.gets
                    puts line
                end
                puts "#{i}th sending"
            end
        end
    end
end
Foi útil?

Solução

Simplicity compared to threads, not speed. Look here for more insights: EventMachine: Fast and Scalable Event-Driven I/O Framework

The citation that applies to your question:

A lot has been written about the fact that event-driven programs are not theoretically any faster than threaded ones, and that is true. But in practice, I think the event-driven model is easier to work with, if you want to get to extremely high scalability and performance while still ensuring maximum robustness. I write programs that have to run for months or years without crashing, leaking memory, or exhibiting any kind of lumpy performance, so in practice, event-driven programming works better. Now, here's the problem with event-driven programming: you have to write "backwards." A threaded model stores your program state (inefficiently) in local variables on a runtime stack. In EM you have to do that yourself, which is very unintuitive to programmers who are used to threads. This is why I'm interested in fibers, because it opens the possibility of writing what looks to the programmer like blocking I/O, but still is evented and uses no threads.

Outras dicas

We just went through this exercise on our project yesterday. Conceptual hurdles abound.

Have a look at this demo rails app by Ilya Grigorik. He uses Apache Benchmark to hit the server concurrently as if you were getting traffic from multiple visitors to your site. This is where you get an advantage from eventmachine. Instead of having all the calls to the database line up behind each other, they are sent in asynchronously and the results are dramatic. If you install the demo you can see the difference by replacing the em_mysql2 adaptor(fast) with the mysql2 adaptor(slow) in database.yml

Likewise, if you hit eventmachine in a loop, you are constrained by the synchronous nature of the loop itself(slow).

One thing - you should call EM.epoll before entering the event loop with EM.run instead of inside it.

EventMachine.epoll
EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8080, Handler)
  puts "Listening..."
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top