в чем преимущество EventMachine

Это мой тестовый пример, я обнаружил, что EM не быстрее, чем обычный TCP-сервер.

сервер ЭМ:

    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..."
    }

и мой контрольный тест:

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

person why    schedule 29.04.2011    source источник
comment
Код Ruby обычно имеет отступ в два пробела, а не в четыре.   -  person Andrew Grimm    schedule 02.05.2011


Ответы (3)


Простота по сравнению с потоками, а не скорость. Дополнительные сведения см. здесь: EventMachine: быстрая и масштабируемая среда ввода-вывода, управляемая событиями

Цитата, которая относится к вашему вопросу:

Много было написано о том, что программы, управляемые событиями, теоретически не быстрее, чем многопоточные, и это правда. Но на практике я думаю, что с моделью, управляемой событиями, проще работать, если вы хотите добиться чрезвычайно высокой масштабируемости и производительности, сохраняя при этом максимальную надежность. Я пишу программы, которые должны работать месяцами или годами без сбоев, утечек памяти или каких-либо скачков производительности, поэтому на практике программирование, управляемое событиями, работает лучше. Теперь проблема с программированием, управляемым событиями: вы должны писать «назад». Потоковая модель сохраняет состояние вашей программы (неэффективно) в локальных переменных в стеке времени выполнения. В EM вы должны сделать это самостоятельно, что очень неинтуитивно для программистов, привыкших к потокам. Вот почему меня интересуют файберы, потому что они открывают возможность написать то, что выглядит для программиста как блокирующий ввод-вывод, но при этом обрабатывается событиями и не использует нити.

person Tomasz Stanczak    schedule 29.04.2011
comment
Я согласен с вашим комментарием о простоте и скорости, но эта цитата неверна на нескольких уровнях. Основным из них является многопоточная модель, которая хранит состояние вашей программы (неэффективно) в локальных переменных в стеке времени выполнения. Каждый поток имеет предварительно выделенный стек, хранение переменных в нем не требует выделения памяти, а только движения указателя стека потока. Не существует универсального решения для дизайна серверных приложений. Это больше касается понимания общих методов и использования правильного для работы. - person Peter Vrabel; 01.04.2014
comment
Урок выучен. Напишите и проверьте комментарий локально, а затем вставьте его, чтобы избежать глупых грамматических ошибок ;) - person Peter Vrabel; 01.04.2014

Мы только вчера выполнили это упражнение в нашем проекте. Концептуальных препятствий предостаточно.

Взгляните на это демонстрационное приложение для рельсов от Ильи Григорика. Он использует Apache Benchmark для одновременного обращения к серверу, как если бы вы получали трафик от нескольких посетителей вашего сайта. Здесь вы получаете преимущество от eventmachine. Вместо того, чтобы все вызовы к базе данных выстраивались друг за другом, они отправляются асинхронно, и результаты впечатляют. Если вы установите демо-версию, вы увидите разницу, заменив адаптер em_mysql2 (быстрый) на адаптер mysql2 (медленный) в файле database.yml.

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

person seph    schedule 29.04.2011

Одна вещь — вы должны вызывать EM.epoll перед входом в цикл обработки событий с помощью EM.run, а не внутри него.

EventMachine.epoll
EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8080, Handler)
  puts "Listening..."
}
person Ian Pointer    schedule 13.03.2014