[njs] Added fast path in njs_chb_utf8_length() for ASCII input.

Dmitry Volyntsev xeioex at nginx.com
Fri May 24 23:01:24 UTC 2024


details:   https://hg.nginx.org/njs/rev/437fc09db765
branches:  
changeset: 2338:437fc09db765
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu May 23 22:50:19 2024 -0700
description:
Added fast path in njs_chb_utf8_length() for ASCII input.

diffstat:

 src/njs_chb.h            |  19 +++++++++++++++++++
 src/test/njs_benchmark.c |  33 +++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 0 deletions(-)

diffs (93 lines):

diff -r 585756e8cafe -r 437fc09db765 src/njs_chb.h
--- a/src/njs_chb.h	Wed May 22 23:08:15 2024 -0700
+++ b/src/njs_chb.h	Thu May 23 22:50:19 2024 -0700
@@ -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;
 
@@ -108,6 +110,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)) {
             return -1;
diff -r 585756e8cafe -r 437fc09db765 src/test/njs_benchmark.c
--- a/src/test/njs_benchmark.c	Wed May 22 23:08:15 2024 -0700
+++ b/src/test/njs_benchmark.c	Thu May 23 22:50:19 2024 -0700
@@ -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_v
     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_v
             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;


More information about the nginx-devel mailing list