Чтение из TCPSocket медленно в Ruby / Rails - PullRequest
0 голосов
/ 01 сентября 2009

У меня есть этот простой кусок кода, который пишет в сокет, а затем читает ответ с сервера. Сервер очень быстрый (каждый раз отвечает в течение 5 мс). Однако, хотя запись в сокет происходит быстро - чтение ответа из сокета всегда НАМНОГО медленнее. Любые подсказки?

module UriTester
  module UriInfo
    class << self
      def send_receive(socket, xml)
#        socket = TCPSocket.open("service.server.com","2316")
        begin
        start = Time.now
          socket.print(xml)           # Send request
        puts "just printed the xml into socket #{Time.now - start}"
        rescue Errno::ECONNRESET
        puts "looks like there is an issue!!!"
          socket = TCPSocket.open("service.server.com","2316")
          socket.print(xml)           # Send request
        end
        response=""
        while (line =socket.recv(1024))
          response += line
          break unless line.grep(/<\/bcap>/).empty?
        end
        puts "SEND_RECEIVE COMPLETED. IN #{Time.now - start}"
#        socket.close
        response
      end
    end
  end
end

Спасибо! * * 1004

1 Ответ

5 голосов
/ 01 сентября 2009

Запись в сокет всегда будет намного быстрее, чем чтение в этом случае, потому что запись локальна для машины, и чтение должно ждать ответа по сети.

Более подробно, когда вызов write / send возвращает все, что система говорит вам, что N байтов были успешно скопированы в буфер пространства ядра сокетов. Это не означает, что данные фактически были отправлены по сети. На самом деле, данные могут храниться в буфере сокета довольно долго (при условии, что вы используете TCP). Это из-за того, что называется алгоритмом Nagle , который предназначен для эффективного использования пропускной способности сети. Эта невидимая задержка Нэгла увеличивает время прохождения туда и обратно и как долго вы получите ответ. Сервер также может задержать ответ по той же причине, увеличивая время отклика.

Так что когда вы пишете время и оно быстро возвращается, это на самом деле ничего не значит.

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

Что вы на самом деле пытаетесь измерить и почему?

...