From 872e291cb1ec49fc74dc8e6d70e80bb7506b7145 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 11 Aug 2015 19:58:43 +0000 Subject: poll: avoid rb_funcall for rb_hash_clear rb_funcall will always be slower, and currently hits the global method cache in MRI. --- ext/kgio/extconf.rb | 1 + ext/kgio/poll.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ext/kgio/extconf.rb b/ext/kgio/extconf.rb index 44888dd..5b0b74a 100644 --- a/ext/kgio/extconf.rb +++ b/ext/kgio/extconf.rb @@ -51,6 +51,7 @@ have_func('rb_thread_call_without_gvl', %w{ruby/thread.h}) have_func('rb_thread_blocking_region') have_func('rb_thread_io_blocking_region') have_func('rb_str_set_len') +have_func("rb_hash_clear", "ruby.h") # Ruby 2.0+ have_func('rb_time_interval') have_func('rb_wait_for_single_fd') have_func('rb_str_subseq') diff --git a/ext/kgio/poll.c b/ext/kgio/poll.c index 1f931e7..1d8ebd1 100644 --- a/ext/kgio/poll.c +++ b/ext/kgio/poll.c @@ -12,8 +12,18 @@ #endif static VALUE sym_wait_readable, sym_wait_writable; + +#ifdef HAVE_RB_HASH_CLEAR /* Ruby >= 2.0 */ +# define my_hash_clear(h) (void)rb_hash_clear(h) +#else /* !HAVE_RB_HASH_CLEAR - Ruby <= 1.9.3 */ static ID id_clear; +static void my_hash_clear(VALUE h) +{ + rb_funcall(h, id_clear, 0); +} +#endif /* HAVE_RB_HASH_CLEAR */ + struct poll_args { struct pollfd *fds; nfds_t nfds; @@ -126,7 +136,7 @@ static VALUE poll_result(int nr, struct poll_args *a) int rc; if ((nfds_t)nr != a->nfds) - rb_funcall(a->ios, id_clear, 0); + my_hash_clear(a->ios); for (; nr > 0; fds++) { if (fds->revents == 0) continue; @@ -218,7 +228,9 @@ void init_kgio_poll(void) sym_wait_readable = ID2SYM(rb_intern("wait_readable")); sym_wait_writable = ID2SYM(rb_intern("wait_writable")); +#ifndef HAVE_RB_HASH_CLEAR id_clear = rb_intern("clear"); +#endif #define c(x) rb_define_const(mKgio,#x,INT2NUM((int)x)) -- cgit v1.2.3-24-ge0c7