summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris HasiƄski <krzysztof.hasinski@gmail.com>2026-01-14 02:41:00 +0100
committerGitHub <noreply@github.com>2026-01-14 14:41:00 +1300
commit6e61496531afea45ec53ebfd1a5db12635fc6ed9 (patch)
treedb37760fd346e2565021452c424e1d10a197f766
parent65a484578072f86586f250ae28712930da14cf53 (diff)
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)
-rw-r--r--io.c6
1 files 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);