patch 9.2.0054: eval_addblob() is inefficient
Commit:
https://github.com/vim/vim/commit/c389ae8c4467e93827a9737abd907ebc27b998b3
Author: Yasuhiro Matsumoto <[email protected]>
Date: Wed Feb 25 19:57:13 2026 +0000
patch 9.2.0054: eval_addblob() is inefficient
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: #19494
Signed-off-by: Yasuhiro Matsumoto <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/blob.c b/src/blob.c
index 691c67958..bbdf2873d 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -165,8 +165,8 @@ blob_equal(
blob_T *b2)
{
int i;
- int len1 = blob_len(b1);
- int len2 = blob_len(b2);
+ long len1 = blob_len(b1);
+ long len2 = blob_len(b2);
// empty and NULL are considered the same
if (len1 == 0 && len2 == 0)
@@ -821,14 +821,14 @@ blob_reduce(
void
blob_reverse(blob_T *b, typval_T *rettv)
{
- int i, len = blob_len(b);
+ long i, len = blob_len(b);
for (i = 0; i < len / 2; i++)
{
- int tmp = blob_get(b, i);
+ int tmp = blob_get(b, (int)i);
- blob_set(b, i, blob_get(b, len - i - 1));
- blob_set(b, len - i - 1, tmp);
+ blob_set(b, (int)i, blob_get(b, (int)(len - i - 1)));
+ blob_set(b, (int)(len - i - 1), tmp);
}
rettv_blob_set(rettv, b);
}
@@ -841,7 +841,7 @@ f_blob2list(typval_T *argvars, typval_T *rettv)
{
blob_T *blob;
list_T *l;
- int i;
+ long i;
if (rettv_list_alloc(rettv) == FAIL)
return;
@@ -851,8 +851,8 @@ f_blob2list(typval_T *argvars, typval_T *rettv)
blob = argvars->vval.v_blob;
l = rettv->vval.v_list;
- for (i = 0; i < blob_len(blob); i++)
- list_append_number(l, blob_get(blob, i));
+ for (i = 0; i < (long)blob_len(blob); i++)
+ list_append_number(l, blob_get(blob, (int)i));
}
/*
diff --git a/src/eval.c b/src/eval.c
index da95f90e8..a23089498 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4132,15 +4132,27 @@ eval_addblob(typval_T *tv1, typval_T *tv2)
blob_T *b1 = tv1->vval.v_blob;
blob_T *b2 = tv2->vval.v_blob;
blob_T *b = blob_alloc();
- int i;
+ long len1, len2;
+ long totallen;
if (b == NULL)
return;
- for (i = 0; i < blob_len(b1); i++)
- ga_append(&b->bv_ga, blob_get(b1, i));
- for (i = 0; i < blob_len(b2); i++)
- ga_append(&b->bv_ga, blob_get(b2, i));
+ len1 = blob_len(b1);
+ len2 = blob_len(b2);
+ totallen = len1 + len2;
+
+ if (totallen > 0 && totallen <= INT_MAX
+ && ga_grow(&b->bv_ga, (int)totallen) == OK)
+ {
+ if (len1 > 0)
+ mch_memmove((char_u *)b->bv_ga.ga_data,
+ (char_u *)b1->bv_ga.ga_data, (size_t)len1);
+ if (len2 > 0)
+ mch_memmove((char_u *)b->bv_ga.ga_data + len1,
+ (char_u *)b2->bv_ga.ga_data, (size_t)len2);
+ b->bv_ga.ga_len = (int)totallen;
+ }
clear_tv(tv1);
rettv_blob_set(tv1, b);
diff --git a/src/version.c b/src/version.c
index fe8ce15a1..473a64fb5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 54,
/**/
53,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1vvL3D-00Ctjq-Rn%40256bit.org.