]> git.kaiwu.me - quickjs.git/commitdiff
faster String.prototype.concat
authorFabrice Bellard <fabrice@bellard.org>
Mon, 26 Oct 2026 12:40:27 +0000 (13:40 +0100)
committerFabrice Bellard <fabrice@bellard.org>
Mon, 26 Oct 2026 12:40:27 +0000 (13:40 +0100)
quickjs.c
tests/microbench.js

index c4ba91561d1f7cb000fa5c3046b5b87df0cde70f..b2a69492eada0320abd7f81bbd8cff08881637ab 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -47787,19 +47787,22 @@ static JSValue js_string_codePointAt(JSContext *ctx, JSValueConst this_val,
 static JSValue js_string_concat(JSContext *ctx, JSValueConst this_val,
                                 int argc, JSValueConst *argv)
 {
+    StringBuffer b_s, *b = &b_s;
     JSValue r;
     int i;
 
-    /* XXX: Use more efficient method */
-    /* XXX: This method is OK if r has a single refcount */
-    /* XXX: should use string_buffer? */
+    string_buffer_init(ctx, b, 0);
     r = JS_ToStringCheckObject(ctx, this_val);
+    if (string_buffer_concat_value_free(b, r))
+        goto fail;
     for (i = 0; i < argc; i++) {
-        if (JS_IsException(r))
-            break;
-        r = JS_ConcatString(ctx, r, JS_DupValue(ctx, argv[i]));
+        if (string_buffer_concat_value(b, argv[i]))
+            goto fail;
     }
-    return r;
+    return string_buffer_end(b);
+ fail:
+    string_buffer_free(b);
+    return JS_EXCEPTION;
 }
 
 static int string_cmp(JSString *p1, JSString *p2, int x1, int x2, int len)
index 37e6a279f6071b33a55fcb836226b83f78ca833a..ca584a32a95bc9089fa7d5087665c1fc3b9cf732 100644 (file)
@@ -1114,6 +1114,40 @@ function string_build_large2(n)
     return n * len;
 }
 
+function string_concat(n)
+{
+    var tab, i, len = 50;
+    tab = [];
+    for(i = 0; i < len; i++)
+        tab.push("x" + i);
+    for(i = 0; i < n; i++) {
+        global_res = String.prototype.concat.apply("", tab);
+    }
+    return n * len;
+}
+
+function string_array_join(n)
+{
+    var tab, i, len = 50;
+    tab = [];
+    for(i = 0; i < len; i++)
+        tab.push("x" + i);
+    for(i = 0; i < n; i++) {
+        global_res = tab.join("");
+    }
+    return n * len;
+}
+
+function string_template(n)
+{
+    var i, a;
+    a = "0";
+    for(i = 0; i < n; i++) {
+        global_res = `x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}x${a}`
+    }
+    return n * 40;
+}
+
 /* sort bench */
 
 function sort_bench(text) {
@@ -1492,6 +1526,9 @@ function main(argc, argv, g)
         string_build4,
         string_build_large1,
         string_build_large2,
+        string_concat,
+        string_array_join,
+        string_template,
         int_to_string,
         int_toString,
         float_to_string,