From 1fe1b2525f7e54dee17a3303e2a2f1f184ef5493 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 26 Feb 2026 08:15:57 +0800 Subject: [PATCH] vim-patch:9.2.0054: eval_addblob() is inefficient (#38067) Problem: eval_addblob() is inefficient Solution: Replace per-byte ga_append() loop with a single ga_grow() and mch_memmove() for each source blob. This eliminates N grow checks and function call overhead for blob concatenation (Yasuhiro Matsumoto). closes: vim/vim#19494 https://github.com/vim/vim/commit/c389ae8c4467e93827a9737abd907ebc27b998b3 Omit the pointless int -> long changes in other functions. Co-authored-by: Yasuhiro Matsumoto --- src/nvim/eval.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 550ac3483f..ab02298d2b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2233,11 +2233,19 @@ static void eval_addblob(typval_T *tv1, typval_T *tv2) const blob_T *const b2 = tv2->vval.v_blob; blob_T *const b = tv_blob_alloc(); - for (int i = 0; i < tv_blob_len(b1); i++) { - ga_append(&b->bv_ga, tv_blob_get(b1, i)); - } - for (int i = 0; i < tv_blob_len(b2); i++) { - ga_append(&b->bv_ga, tv_blob_get(b2, i)); + int64_t len1 = tv_blob_len(b1); + int64_t len2 = tv_blob_len(b2); + int64_t totallen = len1 + len2; + + if (totallen >= 0 && totallen <= INT_MAX) { + ga_grow(&b->bv_ga, (int)totallen); + if (len1 > 0) { + memmove((char *)b->bv_ga.ga_data, b1->bv_ga.ga_data, (size_t)len1); + } + if (len2 > 0) { + memmove((char *)b->bv_ga.ga_data + len1, b2->bv_ga.ga_data, (size_t)len2); + } + b->bv_ga.ga_len = (int)totallen; } tv_clear(tv1);