summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-02 22:22:14 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-02 22:22:14 +0000
commitdf4e282eeb53ba19e6bd72a5a10f89a1989a55a3 (patch)
tree985d687ab1a4860bb6a1cb130a33da7ea5282e19
parent79d757b1470b7cfbc569996d7bf9c223f30d4572 (diff)
delay `exception: false' checks for minor speedup
Delay hash lookups until we are about to hit an exception. This gives a minor speedup ratio of 2-3% in the new bm_io_nonblock_noex benchmark as well as reducing code. * benchmark/bm_io_nonblock_noex.rb: new benchmark * ext/openssl/ossl_ssl.c (no_exception_p): new function (ossl_start_ssl): adjust for no_exception_p (ossl_ssl_connect): adjust ossl_start_ssl call (ossl_ssl_connect_nonblock): ditto (ossl_ssl_accept): ditto (ossl_ssl_accept_nonblock): ditto (ossl_ssl_read_internal): adjust for no_exception_p (ossl_ssl_write_internal): ditto (ossl_ssl_write): adjust ossl_write_internal call (ossl_ssl_write_nonblock): ditto * ext/stringio/stringio.c (strio_read_nonblock): delay exception check * io.c (no_exception_p): new function (io_getpartial): call no_exception_p (io_readpartial): adjust for io_getpartial (get_kwargs_exception): remove (io_read_nonblock): adjust for io_getpartial, check no_exception_p on EOF (io_write_nonblock): call no_exception_p (rb_io_write_nonblock): do not check `exception: false' (argf_getpartial): adjust for io_getpartial [ruby-core:69778] [Feature #11318] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51113 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog26
-rw-r--r--benchmark/bm_io_nonblock_noex.rb22
-rw-r--r--ext/openssl/ossl_ssl.c71
-rw-r--r--ext/stringio/stringio.c7
-rw-r--r--io.c55
5 files changed, 104 insertions, 77 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a6b48357a..07c011544d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+Fri Jul 3 07:21:06 2015 Eric Wong <e@80x24.org>
+
+ * benchmark/bm_io_nonblock_noex.rb: new benchmark
+ * ext/openssl/ossl_ssl.c (no_exception_p): new function
+ (ossl_start_ssl): adjust for no_exception_p
+ (ossl_ssl_connect): adjust ossl_start_ssl call
+ (ossl_ssl_connect_nonblock): ditto
+ (ossl_ssl_accept): ditto
+ (ossl_ssl_accept_nonblock): ditto
+ (ossl_ssl_read_internal): adjust for no_exception_p
+ (ossl_ssl_write_internal): ditto
+ (ossl_ssl_write): adjust ossl_write_internal call
+ (ossl_ssl_write_nonblock): ditto
+ * ext/stringio/stringio.c (strio_read_nonblock):
+ delay exception check
+ * io.c (no_exception_p): new function
+ (io_getpartial): call no_exception_p
+ (io_readpartial): adjust for io_getpartial
+ (get_kwargs_exception): remove
+ (io_read_nonblock): adjust for io_getpartial,
+ check no_exception_p on EOF
+ (io_write_nonblock): call no_exception_p
+ (rb_io_write_nonblock): do not check `exception: false'
+ (argf_getpartial): adjust for io_getpartial
+ [ruby-core:69778] [Feature #11318]
+
Fri Jul 3 07:13:11 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* dir.c (replace_real_basename): Win32 API does not set errno, get
diff --git a/benchmark/bm_io_nonblock_noex.rb b/benchmark/bm_io_nonblock_noex.rb
new file mode 100644
index 0000000000..da9357fdc6
--- /dev/null
+++ b/benchmark/bm_io_nonblock_noex.rb
@@ -0,0 +1,22 @@
+nr = 1_000_000
+i = 0
+msg = '.'
+buf = '.'
+noex = { exception: false }
+begin
+ r, w = IO.pipe
+ while i < nr
+ i += 1
+ w.write_nonblock(msg, noex)
+ r.read_nonblock(1, buf, noex)
+ end
+rescue ArgumentError # old Rubies
+ while i < nr
+ i += 1
+ w.write_nonblock(msg)
+ r.read_nonblock(1, buf)
+ end
+ensure
+ r.close
+ w.close
+end
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 4496d46ab7..143189e5d0 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1273,14 +1273,23 @@ read_would_block(int nonblock)
}
}
+static int
+no_exception_p(VALUE opts)
+{
+ if (RB_TYPE_P(opts, T_HASH) &&
+ rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
+ return 1;
+ return 0;
+}
+
static VALUE
-ossl_start_ssl(VALUE self, int (*func)(), const char *funcname,
- int nonblock, int no_exception)
+ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
{
SSL *ssl;
rb_io_t *fptr;
int ret, ret2;
VALUE cb_state;
+ int nonblock = opts != Qfalse;
rb_ivar_set(self, ID_callback_state, Qnil);
@@ -1299,12 +1308,12 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname,
switch((ret2 = ssl_get_error(ssl, ret))){
case SSL_ERROR_WANT_WRITE:
- if (no_exception) { return sym_wait_writable; }
+ if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
rb_io_wait_writable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_WANT_READ:
- if (no_exception) { return sym_wait_readable; }
+ if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
rb_io_wait_readable(FPTR_TO_FD(fptr));
continue;
@@ -1330,15 +1339,8 @@ static VALUE
ossl_ssl_connect(VALUE self)
{
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0, 0);
-}
-static int
-get_no_exception(VALUE opts)
-{
- if (!NIL_P(opts) && Qfalse == rb_hash_lookup2(opts, sym_exception, Qundef))
- return 1;
- return 0;
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
}
/*
@@ -1366,14 +1368,12 @@ get_no_exception(VALUE opts)
static VALUE
ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
{
- int no_exception;
- VALUE opts = Qnil;
-
+ VALUE opts;
rb_scan_args(argc, argv, "0:", &opts);
- no_exception = get_no_exception(opts);
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1, no_exception);
+
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
}
/*
@@ -1387,7 +1387,8 @@ static VALUE
ossl_ssl_accept(VALUE self)
{
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0, 0);
+
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
}
/*
@@ -1415,14 +1416,12 @@ ossl_ssl_accept(VALUE self)
static VALUE
ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
{
- int no_exception;
- VALUE opts = Qnil;
+ VALUE opts;
rb_scan_args(argc, argv, "0:", &opts);
- no_exception = get_no_exception(opts);
-
ossl_ssl_setup(self);
- return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1, no_exception);
+
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
}
static VALUE
@@ -1430,14 +1429,12 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
{
SSL *ssl;
int ilen, nread = 0;
- int no_exception = 0;
VALUE len, str;
rb_io_t *fptr;
VALUE opts = Qnil;
if (nonblock) {
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
- no_exception = get_no_exception(opts);
} else {
rb_scan_args(argc, argv, "11", &len, &str);
}
@@ -1462,21 +1459,21 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
case SSL_ERROR_NONE:
goto end;
case SSL_ERROR_ZERO_RETURN:
- if (no_exception) { return Qnil; }
+ if (no_exception_p(opts)) { return Qnil; }
rb_eof_error();
case SSL_ERROR_WANT_WRITE:
- if (no_exception) { return sym_wait_writable; }
+ if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
rb_io_wait_writable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_WANT_READ:
- if (no_exception) { return sym_wait_readable; }
+ if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
rb_io_wait_readable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_SYSCALL:
if(ERR_peek_error() == 0 && nread == 0) {
- if (no_exception) { return Qnil; }
+ if (no_exception_p(opts)) { return Qnil; }
rb_eof_error();
}
rb_sys_fail(0);
@@ -1536,11 +1533,12 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
}
static VALUE
-ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
+ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
{
SSL *ssl;
int nwrite = 0;
rb_io_t *fptr;
+ int nonblock = opts != Qfalse;
StringValue(str);
GetSSL(self, ssl);
@@ -1553,12 +1551,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
case SSL_ERROR_NONE:
goto end;
case SSL_ERROR_WANT_WRITE:
- if (no_exception) { return sym_wait_writable; }
+ if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
rb_io_wait_writable(FPTR_TO_FD(fptr));
continue;
case SSL_ERROR_WANT_READ:
- if (no_exception) { return sym_wait_readable; }
+ if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
rb_io_wait_readable(FPTR_TO_FD(fptr));
continue;
@@ -1588,7 +1586,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
- return ossl_ssl_write_internal(self, str, 0, 0);
+ return ossl_ssl_write_internal(self, str, Qfalse);
}
/*
@@ -1601,14 +1599,11 @@ ossl_ssl_write(VALUE self, VALUE str)
static VALUE
ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
{
- VALUE str;
- VALUE opts = Qnil;
- int no_exception;
+ VALUE str, opts;
rb_scan_args(argc, argv, "1:", &str, &opts);
- no_exception = get_no_exception(opts);
- return ossl_ssl_write_internal(self, str, 1, no_exception);
+ return ossl_ssl_write_internal(self, str, opts);
}
/*
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index ed141dda64..89cc392122 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -1359,20 +1359,17 @@ static VALUE
strio_read_nonblock(int argc, VALUE *argv, VALUE self)
{
VALUE opts = Qnil, val;
- int no_exception = 0;
rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
if (!NIL_P(opts)) {
argc--;
-
- if (Qfalse == rb_hash_aref(opts, sym_exception))
- no_exception = 1;
}
val = strio_read(argc, argv, self);
if (NIL_P(val)) {
- if (no_exception)
+ if (!NIL_P(opts) &&
+ rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
return Qnil;
else
rb_eof_error();
diff --git a/io.c b/io.c
index 285d829ced..57ddbb713d 100644
--- a/io.c
+++ b/io.c
@@ -2482,8 +2482,18 @@ read_internal_call(VALUE arg)
return Qundef;
}
+static int
+no_exception_p(VALUE opts)
+{
+ VALUE except;
+ ID id = id_exception;
+
+ rb_get_kwargs(opts, &id, 0, 1, &except);
+ return except == Qfalse;
+}
+
static VALUE
-io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock, int no_exception)
+io_getpartial(int argc, VALUE *argv, VALUE io, VALUE opts, int nonblock)
{
rb_io_t *fptr;
VALUE length, str;
@@ -2523,7 +2533,7 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock, int no_exception)
if (!nonblock && rb_io_wait_readable(fptr->fd))
goto again;
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) {
- if (no_exception)
+ if (no_exception_p(opts))
return sym_wait_readable;
else
rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block");
@@ -2603,25 +2613,12 @@ io_readpartial(int argc, VALUE *argv, VALUE io)
{
VALUE ret;
- ret = io_getpartial(argc, argv, io, 0, 0);
+ ret = io_getpartial(argc, argv, io, Qnil, 0);
if (NIL_P(ret))
rb_eof_error();
return ret;
}
-static VALUE
-get_kwargs_exception(VALUE opts)
-{
- static ID ids[1];
- VALUE except;
-
- if (!ids[0])
- ids[0] = id_exception;
-
- rb_get_kwargs(opts, ids, 0, 1, &except);
- return except;
-}
-
/*
* call-seq:
* ios.read_nonblock(maxlen) -> string
@@ -2676,19 +2673,14 @@ get_kwargs_exception(VALUE opts)
static VALUE
io_read_nonblock(int argc, VALUE *argv, VALUE io)
{
- VALUE ret;
- VALUE opts = Qnil;
- int no_exception = 0;
+ VALUE ret, opts;
rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
- if (!NIL_P(opts) && Qfalse == get_kwargs_exception(opts))
- no_exception = 1;
-
- ret = io_getpartial(argc, argv, io, 1, no_exception);
+ ret = io_getpartial(argc, argv, io, opts, 1);
if (NIL_P(ret)) {
- if (no_exception)
+ if (no_exception_p(opts))
return Qnil;
else
rb_eof_error();
@@ -2697,7 +2689,7 @@ io_read_nonblock(int argc, VALUE *argv, VALUE io)
}
static VALUE
-io_write_nonblock(VALUE io, VALUE str, int no_exception)
+io_write_nonblock(VALUE io, VALUE str, VALUE opts)
{
rb_io_t *fptr;
long n;
@@ -2717,7 +2709,7 @@ io_write_nonblock(VALUE io, VALUE str, int no_exception)
if (n == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
- if (no_exception) {
+ if (no_exception_p(opts)) {
return sym_wait_writable;
}
else {
@@ -2791,16 +2783,11 @@ io_write_nonblock(VALUE io, VALUE str, int no_exception)
static VALUE
rb_io_write_nonblock(int argc, VALUE *argv, VALUE io)
{
- VALUE str;
- VALUE opts = Qnil;
- int no_exceptions = 0;
+ VALUE str, opts;
rb_scan_args(argc, argv, "10:", &str, &opts);
- if (!NIL_P(opts) && Qfalse == get_kwargs_exception(opts))
- no_exceptions = 1;
-
- return io_write_nonblock(io, str, no_exceptions);
+ return io_write_nonblock(io, str, opts);
}
/*
@@ -11218,7 +11205,7 @@ argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock)
RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
}
else {
- tmp = io_getpartial(argc, argv, ARGF.current_file, nonblock, 0);
+ tmp = io_getpartial(argc, argv, ARGF.current_file, Qnil, nonblock);
}
if (NIL_P(tmp)) {
if (ARGF.next_p == -1) {