From 6043490c0a786ce051804b452a865f896bb7bcdc Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 21 Oct 2025 18:15:37 +0900 Subject: [PATCH] mruby-io: hoist RARRAY_PTR calls in IO.select loops Optimizes IO.select by hoisting RARRAY_PTR calls outside loops to avoid repeated conditional checks in both setup and result processing phases. Optimized loops: - Setup phase: 3 loops for read/write/except arrays - Result phase: 3 loops for read/write/except arrays Each loop previously called RARRAY_PTR 1-2 times per iteration. With hoisting, each array pointer is retrieved once per loop instead of once per iteration, significantly reducing overhead in I/O multiplexing. Co-authored-by: Claude --- mrbgems/mruby-io/src/io.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index e6ed14ae6..59864f28a 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -1337,8 +1337,10 @@ io_s_select(mrb_state *mrb, mrb_value klass) rset = mrb_hal_io_fdset_alloc(mrb); rp = rset; mrb_hal_io_fdset_zero(mrb, rp); + /* Hoist pointer retrieval outside loop */ + mrb_value *read_ptr = RARRAY_PTR(read); for (int i = 0; i < RARRAY_LEN(read); i++) { - read_io = RARRAY_PTR(read)[i]; + read_io = read_ptr[i]; fptr = io_get_open_fptr(mrb, read_io); mrb_hal_io_fdset_set(mrb, fptr->fd, rp); if (mrb_io_read_data_pending(mrb, fptr)) { @@ -1361,8 +1363,10 @@ io_s_select(mrb_state *mrb, mrb_value klass) wset = mrb_hal_io_fdset_alloc(mrb); wp = wset; mrb_hal_io_fdset_zero(mrb, wp); + /* Hoist pointer retrieval outside loop */ + mrb_value *write_ptr = RARRAY_PTR(write); for (int i = 0; i < RARRAY_LEN(write); i++) { - fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]); + fptr = io_get_open_fptr(mrb, write_ptr[i]); mrb_hal_io_fdset_set(mrb, fptr->fd, wp); if (max < fptr->fd) max = fptr->fd; @@ -1381,8 +1385,10 @@ io_s_select(mrb_state *mrb, mrb_value klass) eset = mrb_hal_io_fdset_alloc(mrb); ep = eset; mrb_hal_io_fdset_zero(mrb, ep); + /* Hoist pointer retrieval outside loop */ + mrb_value *except_ptr = RARRAY_PTR(except); for (int i = 0; i < RARRAY_LEN(except); i++) { - fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]); + fptr = io_get_open_fptr(mrb, except_ptr[i]); mrb_hal_io_fdset_set(mrb, fptr->fd, ep); if (max < fptr->fd) max = fptr->fd; @@ -1428,37 +1434,46 @@ retry: if (interrupt_flag == 0) { if (rp) { list = RARRAY_PTR(result)[0]; + /* Hoist pointer retrieval outside loop */ + mrb_value *read_ptr = RARRAY_PTR(read); for (int i = 0; i < RARRAY_LEN(read); i++) { - fptr = io_get_open_fptr(mrb, RARRAY_PTR(read)[i]); + mrb_value io = read_ptr[i]; + fptr = io_get_open_fptr(mrb, io); if (mrb_hal_io_fdset_isset(mrb, fptr->fd, rp) || mrb_hal_io_fdset_isset(mrb, fptr->fd, pset)) { - mrb_ary_push(mrb, list, RARRAY_PTR(read)[i]); + mrb_ary_push(mrb, list, io); } } } if (wp) { list = RARRAY_PTR(result)[1]; + /* Hoist pointer retrieval outside loop */ + mrb_value *write_ptr = RARRAY_PTR(write); for (int i = 0; i < RARRAY_LEN(write); i++) { - fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]); + mrb_value io = write_ptr[i]; + fptr = io_get_open_fptr(mrb, io); if (mrb_hal_io_fdset_isset(mrb, fptr->fd, wp)) { - mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); + mrb_ary_push(mrb, list, io); } else if (fptr->fd2 >= 0 && mrb_hal_io_fdset_isset(mrb, fptr->fd2, wp)) { - mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); + mrb_ary_push(mrb, list, io); } } } if (ep) { list = RARRAY_PTR(result)[2]; + /* Hoist pointer retrieval outside loop */ + mrb_value *except_ptr = RARRAY_PTR(except); for (int i = 0; i < RARRAY_LEN(except); i++) { - fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]); + mrb_value io = except_ptr[i]; + fptr = io_get_open_fptr(mrb, io); if (mrb_hal_io_fdset_isset(mrb, fptr->fd, ep)) { - mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); + mrb_ary_push(mrb, list, io); } else if (fptr->fd2 >= 0 && mrb_hal_io_fdset_isset(mrb, fptr->fd2, ep)) { - mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); + mrb_ary_push(mrb, list, io); } } }