Optimize sdscatrepr by batch processing printable characters (#1342)

Optimize sdscatrepr by reducing realloc calls, furthermore, we can reduce memcpy calls by
batch processing of consecutive printable characters.

Signed-off-by: Ray Cao <zisong.cw@alibaba.com>
Co-authored-by: Ray Cao <zisong.cw@alibaba.com>
This commit is contained in:
Ray Cao 2024-11-25 23:16:46 +08:00 committed by GitHub
parent c4920bca4a
commit cf1a1e0931
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -954,23 +954,30 @@ void sdsfreesplitres(sds *tokens, int count) {
sds sdscatrepr(sds s, const char *p, size_t len) {
s = sdsMakeRoomFor(s, len + 2);
s = sdscatlen(s, "\"", 1);
while (len--) {
switch (*p) {
case '\\':
case '"': s = sdscatprintf(s, "\\%c", *p); break;
case '\n': s = sdscatlen(s, "\\n", 2); break;
case '\r': s = sdscatlen(s, "\\r", 2); break;
case '\t': s = sdscatlen(s, "\\t", 2); break;
case '\a': s = sdscatlen(s, "\\a", 2); break;
case '\b': s = sdscatlen(s, "\\b", 2); break;
default:
if (isprint(*p))
s = sdscatlen(s, p, 1);
else
while (len) {
if (isprint(*p)) {
const char *start = p;
while (len && isprint(*p)) {
len--;
p++;
}
s = sdscatlen(s, start, p - start);
} else {
switch (*p) {
case '\\':
case '"': s = sdscatprintf(s, "\\%c", *p); break;
case '\n': s = sdscatlen(s, "\\n", 2); break;
case '\r': s = sdscatlen(s, "\\r", 2); break;
case '\t': s = sdscatlen(s, "\\t", 2); break;
case '\a': s = sdscatlen(s, "\\a", 2); break;
case '\b': s = sdscatlen(s, "\\b", 2); break;
default:
s = sdscatprintf(s, "\\x%02x", (unsigned char)*p);
break;
break;
}
p++;
len--;
}
p++;
}
return sdscatlen(s, "\"", 1);
}