From 1250d031afcfd8cf1fe14637b6906f2c20835b69 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Thu, 23 May 2024 22:50:19 -0700 Subject: [PATCH] Added fast path in njs_chb_utf8_length() for ASCII input. --- src/njs_chb.h | 19 +++++++++++++++++++ src/test/njs_benchmark.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/njs_chb.h b/src/njs_chb.h index 85010728..3dbe5ac9 100644 --- a/src/njs_chb.h +++ b/src/njs_chb.h @@ -96,6 +96,8 @@ njs_chb_size(njs_chb_t *chain) njs_inline int64_t njs_chb_utf8_length(njs_chb_t *chain) { + u_char *p, *p_end; + size_t size; int64_t len, length; njs_chb_node_t *n; @@ -107,6 +109,23 @@ njs_chb_utf8_length(njs_chb_t *chain) length = 0; + while (n != NULL) { + p = n->start; + size = njs_chb_node_size(n); + p_end = p + size; + + while (p < p_end && *p < 0x80) { + p++; + } + + if (p != p_end) { + break; + } + + length += size; + n = n->next; + } + while (n != NULL) { len = njs_utf8_length(n->start, njs_chb_node_size(n)); if (njs_slow_path(len < 0)) { diff --git a/src/test/njs_benchmark.c b/src/test/njs_benchmark.c index 523aa46e..f957dc56 100644 --- a/src/test/njs_benchmark.c +++ b/src/test/njs_benchmark.c @@ -305,6 +305,21 @@ static njs_benchmark_test_t njs_test[] = njs_str("undefined"), 1 }, + { "string create chb 'x'.repeat(256)", + njs_str("benchmark.string('chb', 'x'.repeat(256), 10000)"), + njs_str("undefined"), + 1 }, + + { "string create chb 'Д'.repeat(128)", + njs_str("benchmark.string('chb', 'Д'.repeat(128), 10000)"), + njs_str("undefined"), + 1 }, + + { "string create chb 'x'.repeat(128) + 'Д'.repeat(64)", + njs_str("benchmark.string('chb', 'x'.repeat(128) + 'Д'.repeat(64), 10000)"), + njs_str("undefined"), + 1 }, + { "JSON.parse", njs_str("JSON.parse('{\"a\":123, \"XXX\":[3,4,null]}').a"), njs_str("123"), @@ -696,6 +711,7 @@ njs_benchmark_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { int64_t i, n; + njs_chb_t chain; njs_str_t s, mode; njs_value_t value; @@ -718,6 +734,23 @@ njs_benchmark_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_string_create(vm, &value, s.start, s.length); } + } else if (memcmp(mode.start, "chb", 3) == 0) { + + NJS_CHB_MP_INIT(&chain, vm); + + njs_chb_append_literal(&chain, "abc"); + njs_chb_append(&chain, s.start, s.length); + njs_chb_append_literal(&chain, "abc"); + njs_chb_append(&chain, s.start, s.length); + njs_chb_append_literal(&chain, "abc"); + njs_chb_append(&chain, s.start, s.length); + + for (i = 0; i < n; i++) { + njs_string_create_chb(vm, &value, &chain); + } + + njs_chb_destroy(&chain); + } else { njs_type_error(vm, "unknown mode \"%V\"", &mode); return NJS_ERROR; -- 2.47.3