Project

General

Profile

Actions

Feature #11024

closed

[PATCH] connect_nonblock supports "exception: false"

Added by normalperson (Eric Wong) about 9 years ago. Updated about 9 years ago.

Status:
Closed
Target version:
-
[ruby-core:<unknown>]

Description

This is for consistency with accept_nonblock arguments and gives a
minor speedup from avoiding exceptions:

Results:

             |      user |    system |     total |       real

-----------------|----------:|----------:|----------:|-----------:
default | 0.050000 | 0.100000 | 0.150000 |( 0.151307)
exception: false | 0.030000 | 0.080000 | 0.110000 |( 0.108840)


require 'socket'
require 'benchmark'
require 'io/wait'
require 'tmpdir'

host = "127.#{rand 255}.#{rand 255}.#{rand(254) + 1}"

serv = TCPServer.new(host, 0)

nr = 5000

addr = serv.getsockname
pid = fork do
  begin
    serv.accept.close
  rescue => e
    warn "#$$: #{e.message} (#{e.class})"
  end while true
end
at_exit { Process.kill(:TERM, pid) }
serv.close

Benchmark.bmbm do |x|
  x.report("default") do
    nr.times do
      s = Socket.new(:INET, :STREAM)
      s.setsockopt(:SOL_SOCKET, :SO_REUSEADDR, 1)
      begin
        s.connect_nonblock(addr)
      rescue IO::WaitWritable
        s.wait_writable
      end
      s.close
    end
  end
  x.report("exception: false") do
    nr.times do
      s = Socket.new(:INET, :STREAM)
      s.setsockopt(:SOL_SOCKET, :SO_REUSEADDR, 1)
      case s.connect_nonblock(addr, exception: false)
      when :wait_writable
        s.wait_writable
      end
      s.close
    end
  end
end

Files

Actions #1

Updated by nobu (Nobuyoshi Nakada) about 9 years ago

  • Description updated (diff)

Seems working fine, but my results don't look better, on Ubuntu 14.10
on VirtualBox on OS X.

nr = 5000 user system total real
default 0.000000 0.290000 0.290000 ( 0.291610)
exception: false 0.000000 0.210000 0.210000 ( 0.218066)
nr = 50000 user system total real
default 0.010000 2.840000 2.850000 ( 4.859450)
exception: false 0.020000 2.340000 2.360000 ( 7.369629)
Actions #2

Updated by nobu (Nobuyoshi Nakada) about 9 years ago

I see, no problems then.

As a side note, the benchmark failed unless host is "127.0.0.1" on OSX.

Actions #3

Updated by Anonymous about 9 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

Applied in changeset r50254.


connect_nonblock supports "exception: false"

This is for consistency with accept_nonblock arguments and gives a
minor speedup from avoiding exceptions.
[ruby-core:68838] [Feature #11024]

  • ext/openssl/ossl_ssl.c (ossl_ssl_connect_nonblock):
    support `exception: false'
  • (get_no_exception): move function location
  • ext/socket/socket.c (sock_connect_nonblock):
    support `exception: false'
  • test/openssl/test_pair.rb (test_connect_accept_nonblock_no_exception):
    test exception: false' on connect, rename from test_accept_nonblock_no_exception'
  • test/socket/test_nonblock.rb (test_connect_nonblock_no_exception):
    new test

Benchmark results:

default 0.050000 0.100000 0.150000 ( 0.151307)
exception: false 0.030000 0.080000 0.110000 ( 0.108840)

----------------------------8<-----------------------
require 'socket'
require 'benchmark'
require 'io/wait'
require 'tmpdir'

host = '127.0.0.1'
serv = TCPServer.new(host, 0) # UNIX sockets may not hit EINPROGRESS

nr = 5000 # few iterations to avoid running out of ports

addr = serv.getsockname
pid = fork do
begin
serv.accept.close
rescue => e
warn "#$$: #{e.message} (#{e.class})"
end while true
end
at_exit { Process.kill(:TERM, pid) }
serv.close

Benchmark.bmbm do |x|
x.report("default") do
nr.times do
s = Socket.new(:INET, :STREAM)
s.setsockopt(:SOL_SOCKET, :SO_REUSEADDR, 1)
begin
s.connect_nonblock(addr)
rescue IO::WaitWritable
s.wait_writable
end
s.close
end
end
x.report("exception: false") do
nr.times do
s = Socket.new(:INET, :STREAM)
s.setsockopt(:SOL_SOCKET, :SO_REUSEADDR, 1)
case s.connect_nonblock(addr, exception: false)
when :wait_writable
s.wait_writable
end
s.close
end
end
end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0