diff options
author | Matt Mastracci <matthew@mastracci.com> | 2023-04-30 10:50:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-30 08:50:24 +0000 |
commit | bb1f5e4262940a966e6314f57a4267514911d262 (patch) | |
tree | 0b5b870e34fca10daf8e664eb4214e5e756daf53 /cli | |
parent | 9c8ebce3dcc784f1a6ecd29d5fe0b3d35256ab82 (diff) |
perf(core): async op pseudo-codegen and performance work (#18887)
Performance:
```
async_ops.js: 760k -> 1030k (!)
async_ops_deferred.js: 730k -> 770k
Deno.serve bench: 118k -> 124k
WS test w/ third_party/prebuilt/mac/load_test 100 localhost 8000 0 0: unchanged
Startup time: approx 0.5ms slower (13.7 -> 14.2ms)
```
Diffstat (limited to 'cli')
-rw-r--r-- | cli/bench/async_ops.js | 4 | ||||
-rw-r--r-- | cli/bench/async_ops_deferred.js | 4 | ||||
-rw-r--r-- | cli/tests/unit/metrics_test.ts | 10 | ||||
-rw-r--r-- | cli/tests/unit/opcall_test.ts | 33 | ||||
-rw-r--r-- | cli/tsc/compiler.d.ts | 2 |
5 files changed, 42 insertions, 11 deletions
diff --git a/cli/bench/async_ops.js b/cli/bench/async_ops.js index fc04942be..f6c1465d2 100644 --- a/cli/bench/async_ops.js +++ b/cli/bench/async_ops.js @@ -17,4 +17,6 @@ async function bench(fun) { } const core = Deno[Deno.internal].core; -bench(() => core.opAsync("op_void_async")); +const ops = core.ops; +const opVoidAsync = ops.op_void_async; +bench(() => opVoidAsync()); diff --git a/cli/bench/async_ops_deferred.js b/cli/bench/async_ops_deferred.js index 7a816cf95..2751ad226 100644 --- a/cli/bench/async_ops_deferred.js +++ b/cli/bench/async_ops_deferred.js @@ -17,4 +17,6 @@ async function bench(fun) { } const core = Deno[Deno.internal].core; -bench(() => core.opAsync("op_void_async_deferred")); +const ops = core.ops; +const opVoidAsyncDeferred = ops.op_void_async_deferred; +bench(() => opVoidAsyncDeferred()); diff --git a/cli/tests/unit/metrics_test.ts b/cli/tests/unit/metrics_test.ts index df2f1b2be..5fdfebc85 100644 --- a/cli/tests/unit/metrics_test.ts +++ b/cli/tests/unit/metrics_test.ts @@ -80,12 +80,14 @@ Deno.test(function metricsForOpCrates() { // Test that op_names == Objects.keys(Deno[Deno.internal].core.ops) // since building the per-op metrics depends on op_names being complete Deno.test(function opNamesMatch() { + // @ts-ignore: Deno[Deno.internal].core allowed + const ops = Object.keys(Deno[Deno.internal].core.ops); + // @ts-ignore: Deno[Deno.internal].core allowed + ops.concat(Object.keys(Deno[Deno.internal].core.asyncOps)); + assertEquals( // @ts-ignore: Deno[Deno.internal].core allowed Deno[Deno.internal].core.opNames().sort(), - // @ts-ignore: Deno[Deno.internal].core allowed - Object.keys(Deno[Deno.internal].core.ops).sort().filter((name) => - name !== "asyncOpsInfo" - ), + ops.sort().filter((name) => name !== "asyncOpsInfo"), ); }); diff --git a/cli/tests/unit/opcall_test.ts b/cli/tests/unit/opcall_test.ts index 8985c9780..3b37f8c09 100644 --- a/cli/tests/unit/opcall_test.ts +++ b/cli/tests/unit/opcall_test.ts @@ -1,20 +1,18 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +import { assertEquals } from "https://deno.land/std@v0.42.0/testing/asserts.ts"; import { assert, assertStringIncludes, unreachable } from "./test_util.ts"; Deno.test(async function sendAsyncStackTrace() { - const buf = new Uint8Array(10); - const rid = 10; try { - await Deno.read(rid, buf); + await core.ops.op_error_async(); unreachable(); } catch (error) { assert(error instanceof Error); const s = error.stack?.toString(); assert(s); - console.log(s); assertStringIncludes(s, "opcall_test.ts"); - assertStringIncludes(s, "read"); + assertStringIncludes(s, "sendAsyncStackTrace"); assert( !s.includes("ext:core"), "opcall stack traces should NOT include ext:core internals such as unwrapOpResult", @@ -22,6 +20,31 @@ Deno.test(async function sendAsyncStackTrace() { } }); +Deno.test(async function sendAsyncStackTraceDeferred() { + try { + await core.ops.op_error_async_deferred(); + unreachable(); + } catch (error) { + assert(error instanceof Error); + const s = error.stack?.toString(); + assert(s); + assertStringIncludes(s, "opcall_test.ts"); + assertStringIncludes(s, "sendAsyncStackTraceDeferred"); + assert( + !s.includes("ext:core"), + "opcall stack traces should NOT include ext:core internals such as unwrapOpResult", + ); + } +}); + +Deno.test(function syncAdd() { + assertEquals(30, core.ops.op_add(10, 20)); +}); + +Deno.test(async function asyncAdd() { + assertEquals(30, await core.ops.op_add_async(10, 20)); +}); + // @ts-ignore This is not publicly typed namespace, but it's there for sure. const core = Deno[Deno.internal].core; diff --git a/cli/tsc/compiler.d.ts b/cli/tsc/compiler.d.ts index b59f6dca8..66c094697 100644 --- a/cli/tsc/compiler.d.ts +++ b/cli/tsc/compiler.d.ts @@ -46,6 +46,8 @@ declare global { encode(value: string): Uint8Array; // deno-lint-ignore no-explicit-any ops: Record<string, (...args: unknown[]) => any>; + // deno-lint-ignore no-explicit-any + asyncOps: Record<string, (...args: unknown[]) => any>; print(msg: string, stderr: boolean): void; registerErrorClass( name: string, |