patch 9.2.0431: blob encoding can be improved
Commit:
https://github.com/vim/vim/commit/e1e92fea92ed80dd10ff0cb325433a97c1826b6a
Author: Yasuhiro Matsumoto <[email protected]>
Date: Sat May 2 15:39:55 2026 +0000
patch 9.2.0431: blob encoding can be improved
Problem: blob encoding can be improved
Solution: Speed up blob encoding by avoiding per-byte ga_append()
(Yasuhiro Matsumoto)
Replace the per-byte ga_append loop in the VAR_BLOB branch of
json_encode_item() with a single ga_grow for the worst case
(2 + 4 * blen) and direct writes through a local pointer. Also
read blob bytes through a local char_u* instead of going through
blob_get() for each byte.
Benchmark (1 MiB blob, 5 iterations, total seconds, median of 3 runs):
| byte distribution | Before | After | Speedup |
|---|---:|---:|---:|
| 1-digit (0–9) | 0.0254 | 0.0174 | 1.46x |
| 2-digit (10–99) | 0.0344 | 0.0064 | 5.38x |
| 3-digit (100–255) | 0.0539 | 0.0102 | 5.28x |
| mixed (0–255) | 0.0335 | 0.0093 | 3.60x |
closes: #20113
Signed-off-by: Yasuhiro Matsumoto <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/json.c b/src/json.c
index b0d98a290..a3e58043d 100644
--- a/src/json.c
+++ b/src/json.c
@@ -369,29 +369,38 @@ json_encode_item(garray_T *gap, typval_T *val, int
copyID, int options)
GA_CONCAT_LITERAL(gap, "[]");
else
{
- ga_append(gap, '[');
- for (i = 0; i < b->bv_ga.ga_len; i++)
+ int blen = b->bv_ga.ga_len;
+ char_u *src;
+ char_u *dst;
+
+ // Worst case: '[' + ']' + per-byte 3 digits + comma = 2 +
4*blen
+ if (ga_grow(gap, 2 + 4 * blen) == FAIL)
+ goto theend;
+ src = (char_u *)b->bv_ga.ga_data;
+ dst = (char_u *)gap->ga_data + gap->ga_len;
+ *dst++ = '[';
+ for (i = 0; i < blen; i++)
{
- int byte = blob_get(b, i);
+ int byte = src[i];
if (i > 0)
- ga_append(gap, ',');
- // blob bytes are 0-255, use simple conversion
+ *dst++ = ',';
if (byte >= 100)
{
- ga_append(gap, '0' + byte / 100);
- ga_append(gap, '0' + (byte / 10) % 10);
- ga_append(gap, '0' + byte % 10);
+ *dst++ = '0' + byte / 100;
+ *dst++ = '0' + (byte / 10) % 10;
+ *dst++ = '0' + byte % 10;
}
else if (byte >= 10)
{
- ga_append(gap, '0' + byte / 10);
- ga_append(gap, '0' + byte % 10);
+ *dst++ = '0' + byte / 10;
+ *dst++ = '0' + byte % 10;
}
else
- ga_append(gap, '0' + byte);
+ *dst++ = '0' + byte;
}
- ga_append(gap, ']');
+ *dst++ = ']';
+ gap->ga_len = (int)(dst - (char_u *)gap->ga_data);
}
break;
diff --git a/src/version.c b/src/version.c
index 0ce32fb2e..9208a5078 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 431,
/**/
430,
/**/
--
--
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/E1wJCWe-002FWv-In%40256bit.org.