vim-patch:9.1.2030: inefficient use of ga_concat() (#37151)

Problem:  inefficient use of ga_concat()
Solution: Use ga_concat_len() when length is known.
          (John Marriott)

closes: vim/vim#19027

32b801abc3

Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
zeertzjq
2025-12-29 07:56:45 +08:00
committed by GitHub
parent c53fb58c15
commit e916f03277
4 changed files with 42 additions and 29 deletions

View File

@@ -4057,7 +4057,7 @@ static int copy_substring_from_pos(pos_T *start, pos_T *end, char **match, pos_T
ga_concat_len(&ga, start_ptr, (size_t)segment_len);
if (!is_single_line) {
if (exacttext) {
ga_concat_len(&ga, "\\n", 2);
ga_concat_len(&ga, S_LEN("\\n"));
} else {
ga_append(&ga, '\n');
}
@@ -4067,10 +4067,11 @@ static int copy_substring_from_pos(pos_T *start, pos_T *end, char **match, pos_T
if (!is_single_line) {
for (linenr_T lnum = start->lnum + 1; lnum < end->lnum; lnum++) {
char *line = ml_get(lnum);
ga_grow(&ga, ml_get_len(lnum) + 2);
ga_concat(&ga, line);
int linelen = ml_get_len(lnum);
ga_grow(&ga, linelen + 2);
ga_concat_len(&ga, line, (size_t)linelen);
if (exacttext) {
ga_concat_len(&ga, "\\n", 2);
ga_concat_len(&ga, S_LEN("\\n"));
} else {
ga_append(&ga, '\n');
}

View File

@@ -124,7 +124,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
const char *const partial_self_msg = _("partial self dictionary");
for (size_t i = 0; i < kv_size(*mpstack); i++) {
if (i != 0) {
ga_concat(&msg_ga, ", ");
ga_concat_len(&msg_ga, S_LEN(", "));
}
MPConvStackVal v = kv_A(*mpstack, i);
switch (v.type) {
@@ -296,7 +296,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
do { \
const char *const buf_ = (buf); \
if (buf_ == NULL) { \
ga_concat(gap, "''"); \
ga_concat_len(gap, S_LEN("''")); \
} else { \
const size_t len_ = (len); \
ga_grow(gap, (int)(2 + len_ + memcnt(buf_, '\'', len_))); \
@@ -321,13 +321,13 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
const blob_T *const blob_ = (blob); \
const int len_ = (len); \
if (len_ == 0) { \
ga_concat(gap, "0z"); \
ga_concat_len(gap, S_LEN("0z")); \
} else { \
/* Allocate space for "0z", the two hex chars per byte, and a */ \
/* "." separator after every eight hex chars. */ \
/* Example: "0z00112233.44556677.8899" */ \
ga_grow(gap, 2 + 2 * len_ + (len_ - 1) / 4); \
ga_concat(gap, "0z"); \
ga_concat_len(gap, S_LEN("0z")); \
char numbuf[NUMBUFLEN]; \
for (int i_ = 0; i_ < len_; i_++) { \
if (i_ > 0 && (i_ & 3) == 0) { \
@@ -352,14 +352,14 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
const float_T flt_ = (flt); \
switch (xfpclassify(flt_)) { \
case FP_NAN: { \
ga_concat(gap, "str2float('nan')"); \
ga_concat_len(gap, S_LEN("str2float('nan')")); \
break; \
} \
case FP_INFINITE: { \
if (flt_ < 0) { \
ga_append(gap, '-'); \
} \
ga_concat(gap, "str2float('inf')"); \
ga_concat_len(gap, S_LEN("str2float('inf')")); \
break; \
} \
default: { \
@@ -375,10 +375,10 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
const char *const fun_ = (fun); \
if (fun_ == NULL) { \
internal_error("string(): NULL function name"); \
ga_concat(gap, "function(NULL"); \
ga_concat_len(gap, S_LEN("function(NULL")); \
} else { \
const char *const prefix_ = (prefix); \
ga_concat(gap, "function("); \
ga_concat_len(gap, S_LEN("function(")); \
const int name_off = gap->ga_len; \
ga_concat(gap, prefix_); \
TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
@@ -391,14 +391,14 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \
do { \
if ((len) != 0) { \
ga_concat(gap, ", "); \
ga_concat_len(gap, S_LEN(", ")); \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \
do { \
if ((ptrdiff_t)(len) != -1) { \
ga_concat(gap, ", "); \
ga_concat_len(gap, S_LEN(", ")); \
} \
} while (0)
@@ -406,7 +406,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
ga_append(gap, ')')
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
ga_concat(gap, "[]")
ga_concat_len(gap, S_LEN("[]"))
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
ga_append(gap, '[')
@@ -414,15 +414,21 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
ga_concat(gap, "{}")
ga_concat_len(gap, S_LEN("{}"))
#define TYPVAL_ENCODE_CHECK_BEFORE
#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "v:null")
ga_concat_len(gap, S_LEN("v:null"))
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
ga_concat(gap, ((num) ? "v:true" : "v:false"))
do { \
if (num) { \
ga_concat_len(gap, S_LEN("v:true")); \
} else { \
ga_concat_len(gap, S_LEN("v:false")); \
} \
} while (0)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
@@ -435,10 +441,10 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
ga_append(gap, '}')
#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
ga_concat(gap, ": ")
ga_concat_len(gap, S_LEN(": "))
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
ga_concat(gap, ", ")
ga_concat_len(gap, S_LEN(", "))
#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
@@ -546,11 +552,17 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#undef TYPVAL_ENCODE_CONV_NIL
#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "null")
ga_concat_len(gap, S_LEN("null"))
#undef TYPVAL_ENCODE_CONV_BOOL
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
ga_concat(gap, ((num) ? "true" : "false"))
do { \
if (num) { \
ga_concat_len(gap, S_LEN("true")); \
} else { \
ga_concat_len(gap, S_LEN("false")); \
} \
} while (0)
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
@@ -608,7 +620,7 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const
{
const char *utf_buf = buf;
if (utf_buf == NULL) {
ga_concat(gap, "\"\"");
ga_concat_len(gap, S_LEN("\"\""));
} else {
size_t utf_len = len;
char *tofree = NULL;
@@ -737,13 +749,13 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const
const blob_T *const blob_ = (blob); \
const int len_ = (len); \
if (len_ == 0) { \
ga_concat(gap, "[]"); \
ga_concat_len(gap, S_LEN("[]")); \
} else { \
ga_append(gap, '['); \
char numbuf[NUMBUFLEN]; \
for (int i_ = 0; i_ < len_; i_++) { \
if (i_ > 0) { \
ga_concat(gap, ", "); \
ga_concat_len(gap, S_LEN(", ")); \
} \
vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%d", \
(int)tv_blob_get(blob_, i_)); \

View File

@@ -3192,7 +3192,7 @@ char *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
emsg(_(e_cmd_mapping_must_end_with_cr_before_second_cmd));
aborted = true;
} else if (c1 == K_SNR) {
ga_concat(&line_ga, "<SNR>");
ga_concat_len(&line_ga, S_LEN("<SNR>"));
} else {
if (cmod != 0) {
ga_append(&line_ga, K_SPECIAL);

View File

@@ -11587,9 +11587,9 @@ static void nfa_print_state2(FILE *debugf, nfa_state_T *state, garray_T *indent)
// grow indent for state->out
indent->ga_len -= 1;
if (state->out1) {
ga_concat(indent, (uint8_t *)"| ");
ga_concat(indent, S_LEN("| "));
} else {
ga_concat(indent, (uint8_t *)" ");
ga_concat(indent, S_LEN(" "));
}
ga_append(indent, NUL);
@@ -11597,7 +11597,7 @@ static void nfa_print_state2(FILE *debugf, nfa_state_T *state, garray_T *indent)
// replace last part of indent for state->out1
indent->ga_len -= 3;
ga_concat(indent, (uint8_t *)" ");
ga_concat(indent, S_LEN(" "));
ga_append(indent, NUL);
nfa_print_state2(debugf, state->out1, indent);