]> git.kaiwu.me - njs.git/commitdiff
Optimizing njs_builtin_match_native_function() for speed.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 18 Jun 2020 18:56:24 +0000 (18:56 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 18 Jun 2020 18:56:24 +0000 (18:56 +0000)
src/njs_builtin.c
src/njs_vm.h

index 8aa1ec4e6be2e0c7ebb8958728a725a54f5e42ca..931094b1f53b222cfe38e7b2604090767fae1d49 100644 (file)
@@ -688,17 +688,45 @@ done:
 }
 
 
+typedef struct {
+    njs_str_t               name;
+    njs_function_native_t   native;
+    uint8_t                 magic8;
+} njs_function_name_t;
+
+
 njs_int_t
 njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
     njs_str_t *name)
 {
+    uint8_t                 magic8;
     njs_int_t               ret;
-    njs_uint_t              i;
+    njs_uint_t              i, n;
     njs_value_t             value;
     njs_module_t            *module;
     njs_lvlhsh_each_t       lhe;
+    njs_function_name_t     *fn;
+    njs_function_native_t   native;
     njs_builtin_traverse_t  ctx;
 
+    if (vm->functions_name_cache != NULL) {
+        n = vm->functions_name_cache->items;
+        fn = vm->functions_name_cache->start;
+
+        magic8 = function->magic8;
+        native = function->u.native;
+
+        while (n != 0) {
+            if (fn->native == native && fn->magic8 == magic8) {
+                *name = fn->name;
+                return NJS_OK;
+            }
+
+            fn++;
+            n--;
+        }
+    }
+
     ctx.type = NJS_BUILTIN_TRAVERSE_MATCH;
     ctx.func = function;
 
@@ -710,8 +738,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
                               njs_builtin_traverse);
 
     if (ret == NJS_DONE) {
-        *name = ctx.match;
-        return NJS_OK;
+        goto found;
     }
 
     /* Constructor from built-in modules (not-mapped to global object). */
@@ -730,8 +757,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
                                   njs_builtin_traverse);
 
         if (ret == NJS_DONE) {
-            *name = ctx.match;
-            return NJS_OK;
+            goto found;
         }
     }
 
@@ -752,12 +778,35 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
                                   njs_builtin_traverse);
 
         if (ret == NJS_DONE) {
-            *name = ctx.match;
-            return NJS_OK;
+            goto found;
         }
     }
 
     return NJS_DECLINED;
+
+found:
+
+    if (vm->functions_name_cache == NULL) {
+        vm->functions_name_cache = njs_arr_create(vm->mem_pool, 4,
+                                                  sizeof(njs_function_name_t));
+        if (njs_slow_path(vm->functions_name_cache == NULL)) {
+            return NJS_ERROR;
+        }
+    }
+
+    fn = njs_arr_add(vm->functions_name_cache);
+    if (njs_slow_path(fn == NULL)) {
+        njs_memory_error(vm);
+        return NJS_ERROR;
+    }
+
+    fn->name = ctx.match;
+    fn->native = function->u.native;
+    fn->magic8 = function->magic8;
+
+    *name = fn->name;
+
+    return NJS_OK;
 }
 
 
index 28b8543c1ec1a795a175c1a5e1c4efb58ff8317d..923eb7c53325e70be8d2bc165ae5e02214933ed2 100644 (file)
@@ -223,6 +223,8 @@ struct njs_vm_s {
     njs_uint_t               main_index;
     njs_arr_t                *codes;  /* of njs_vm_code_t */
 
+    njs_arr_t                *functions_name_cache;
+
     njs_trace_t              trace;
     njs_random_t             random;