From 6e61496531afea45ec53ebfd1a5db12635fc6ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Hasi=C5=84ski?= Date: Wed, 14 Jan 2026 02:41:00 +0100 Subject: Pre-allocate IO.select result arrays based on input size (#15850) io.c: pre-allocate IO.select result arrays based on input size The ternary (rp?rb_ary_new():rb_ary_new2(0)) became pointless after commit a51f30c671 (Variable Width Allocation, Mar 2022) made both rb_ary_new() and rb_ary_new2(0) equivalent. Instead of just removing the dead code, improve on the original intent by pre-allocating based on the actual input array size. This avoids reallocations when many FDs are ready. Benchmark (100 ready FDs): ~8% improvement (5.59 -> 5.11 us/op) --- io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/io.c b/io.c index 95664c0230..25c66550f5 100644 --- a/io.c +++ b/io.c @@ -10758,9 +10758,9 @@ select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fd if (!pending && n == 0) return Qnil; /* returns nil on timeout */ res = rb_ary_new2(3); - rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0)); - rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0)); - rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0)); + rb_ary_push(res, rp ? rb_ary_new_capa(RARRAY_LEN(read)) : rb_ary_new()); + rb_ary_push(res, wp ? rb_ary_new_capa(RARRAY_LEN(write)) : rb_ary_new()); + rb_ary_push(res, ep ? rb_ary_new_capa(RARRAY_LEN(except)) : rb_ary_new()); if (rp) { list = RARRAY_AREF(res, 0); -- cgit v1.2.3