Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: "deno bench" subcommand #13713

Merged
merged 54 commits into from Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
54df462
basic boilerplate
bartlomieju Feb 19, 2022
f0ddf87
execute module
bartlomieju Feb 19, 2022
1356b5c
lint
bartlomieju Feb 19, 2022
405f99e
fix flags test
bartlomieju Feb 19, 2022
f3164ce
definitions
bartlomieju Feb 21, 2022
ead4cd3
fix
bartlomieju Feb 21, 2022
7e1b0cd
run iterations
bartlomieju Feb 21, 2022
306f3da
fmt
bartlomieju Feb 21, 2022
9ca828b
create BenchReporter
bartlomieju Feb 21, 2022
4d1ce40
output
bartlomieju Feb 22, 2022
03c44d2
nano seconds measurements
bartlomieju Feb 22, 2022
4189a6a
output
bartlomieju Feb 22, 2022
98d7c7e
formatting, mix, max
bartlomieju Feb 22, 2022
b68c5db
measure without sanitizers
bartlomieju Feb 22, 2022
8eb08a3
lint
bartlomieju Feb 22, 2022
0a91ef2
WIP: warmup iterations
bartlomieju Feb 24, 2022
3277250
Merge branch 'main' into deno_bench
bartlomieju Feb 25, 2022
3d67fe6
fmt
bartlomieju Feb 25, 2022
8b1a4e5
Merge branch 'main' into deno_bench
bartlomieju Feb 26, 2022
ad4ef7e
disable warmup
bartlomieju Feb 26, 2022
c59bbb4
add warmup runs
bartlomieju Feb 26, 2022
f33f048
Merge branch 'main' into deno_bench
bartlomieju Feb 28, 2022
966730d
Merge branch 'main' into deno_bench
bartlomieju Mar 3, 2022
cc9e647
remove op sanitizer
bartlomieju Mar 3, 2022
622b141
remove resource sanitizer
bartlomieju Mar 3, 2022
9b80852
revert unrealted changes
bartlomieju Mar 3, 2022
94e69b7
revert unrealted changes 2
bartlomieju Mar 3, 2022
23da38c
Merge branch 'main' into deno_bench
bartlomieju Mar 5, 2022
b151297
add tests
bartlomieju Mar 5, 2022
46185ac
add more tests
bartlomieju Mar 5, 2022
9edeca7
Merge branch 'main' into deno_bench
bartlomieju Mar 8, 2022
84a7e4b
fix tests
bartlomieju Mar 8, 2022
c0b7ac5
fix tests2
bartlomieju Mar 8, 2022
fa1f706
Merge branch 'main' into deno_bench
bartlomieju Mar 8, 2022
8e76fc7
review first part
bartlomieju Mar 8, 2022
c2c3271
Merge branch 'main' into deno_bench
bartlomieju Mar 8, 2022
9b17e58
don't use additional thread
bartlomieju Mar 8, 2022
78b248c
Merge branch 'main' into deno_bench
bartlomieju Mar 8, 2022
a0a5b36
display::human_elapsed
bartlomieju Mar 8, 2022
495555b
add support for --watch flag
bartlomieju Mar 8, 2022
28e85ad
Merge branch 'main' into deno_bench
bartlomieju Mar 9, 2022
bac0c38
use spawn instead of spawn_blocking
bartlomieju Mar 9, 2022
18900d7
reset CI
bartlomieju Mar 9, 2022
9aa6ab3
Merge branch 'main' into deno_bench
bartlomieju Mar 9, 2022
18a7d6d
remove example files
bartlomieju Mar 9, 2022
1d3a8d6
Update cli/tools/bench.rs
bartlomieju Mar 9, 2022
5ef9308
add op for measuring time
bartlomieju Mar 10, 2022
28957d0
Merge branch 'main' into deno_bench
bartlomieju Mar 11, 2022
7ff4386
use Deno.PermissionOptions
bartlomieju Mar 11, 2022
7808356
reset CI
bartlomieju Mar 11, 2022
5890304
reset CI
bartlomieju Mar 11, 2022
4a56937
Merge branch 'main' into deno_bench
bartlomieju Mar 11, 2022
07d3828
lint
bartlomieju Mar 11, 2022
b8a87e4
Merge branch 'main' into deno_bench
bartlomieju Mar 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cli/Cargo.toml
Expand Up @@ -76,6 +76,7 @@ log = { version = "=0.4.14", features = ["serde"] }
lspower = "=1.4.0"
node_resolver = "0.1.0"
notify = "=5.0.0-pre.12"
num-format = "=0.4.0"
once_cell = "=1.9.0"
percent-encoding = "=2.1.0"
pin-project = "=1.0.8"
Expand Down
1 change: 1 addition & 0 deletions cli/dts/lib.deno.ns.d.ts
Expand Up @@ -453,6 +453,7 @@ declare namespace Deno {
options: Omit<TestDefinition, "fn" | "name">,
fn: (t: TestContext) => void | Promise<void>,
): void;

/** Exit the Deno process with optional exit code. If no exit code is supplied
* then Deno will exit with return code of 0.
*
Expand Down
305 changes: 305 additions & 0 deletions cli/dts/lib.deno.unstable.d.ts
Expand Up @@ -4,6 +4,311 @@
/// <reference lib="deno.ns" />

declare namespace Deno {
export interface BenchDefinition {
fn: () => void | Promise<void>;
name: string;
ignore?: boolean;
/** Specify number of iterations benchmark should perform. Defaults to 1000. */
n?: number;
/** Specify number of warmup iterations benchmark should perform. Defaults
* to 1000.
*
* These iterations are not measured. It allows the code to be optimized
* by JIT compiler before measuring its performance. */
warmup?: number;
/** If at least one bench has `only` set to true, only run benches that have
* `only` set to true and fail the bench suite. */
only?: boolean;
/** Ensure the bench case does not prematurely cause the process to exit,
* for example via a call to `Deno.exit`. Defaults to true. */
sanitizeExit?: boolean;

/** Specifies the permissions that should be used to run the bench.
* Set this to "inherit" to keep the calling thread's permissions.
* Set this to "none" to revoke all permissions.
*
* Defaults to "inherit".
*/
permissions?: "inherit" | "none" | {
bartlomieju marked this conversation as resolved.
Show resolved Hide resolved
/** Specifies if the `net` permission should be requested or revoked.
* If set to `"inherit"`, the current `env` permission will be inherited.
* If set to `true`, the global `net` permission will be requested.
* If set to `false`, the global `net` permission will be revoked.
*
* Defaults to "inherit".
*/
env?: "inherit" | boolean | string[];

/** Specifies if the `hrtime` permission should be requested or revoked.
* If set to `"inherit"`, the current `hrtime` permission will be inherited.
* If set to `true`, the global `hrtime` permission will be requested.
* If set to `false`, the global `hrtime` permission will be revoked.
*
* Defaults to "inherit".
*/
hrtime?: "inherit" | boolean;

/** Specifies if the `net` permission should be requested or revoked.
* if set to `"inherit"`, the current `net` permission will be inherited.
* if set to `true`, the global `net` permission will be requested.
* if set to `false`, the global `net` permission will be revoked.
* if set to `string[]`, the `net` permission will be requested with the
* specified host strings with the format `"<host>[:<port>]`.
*
* Defaults to "inherit".
*
* Examples:
*
* ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({
* name: "inherit",
* permissions: {
* net: "inherit",
* },
* async fn() {
* const status = await Deno.permissions.query({ name: "net" })
* assertEquals(status.state, "granted");
* },
* });
* ```
*
* ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({
* name: "true",
* permissions: {
* net: true,
* },
* async fn() {
* const status = await Deno.permissions.query({ name: "net" });
* assertEquals(status.state, "granted");
* },
* });
* ```
*
* ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({
* name: "false",
* permissions: {
* net: false,
* },
* async fn() {
* const status = await Deno.permissions.query({ name: "net" });
* assertEquals(status.state, "denied");
* },
* });
* ```
*
* ```ts
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({
* name: "localhost:8080",
* permissions: {
* net: ["localhost:8080"],
* },
* async fn() {
* const status = await Deno.permissions.query({ name: "net", host: "localhost:8080" });
* assertEquals(status.state, "granted");
* },
* });
* ```
*/
net?: "inherit" | boolean | string[];

/** Specifies if the `ffi` permission should be requested or revoked.
* If set to `"inherit"`, the current `ffi` permission will be inherited.
* If set to `true`, the global `ffi` permission will be requested.
* If set to `false`, the global `ffi` permission will be revoked.
*
* Defaults to "inherit".
*/
ffi?: "inherit" | boolean | Array<string | URL>;

/** Specifies if the `read` permission should be requested or revoked.
* If set to `"inherit"`, the current `read` permission will be inherited.
* If set to `true`, the global `read` permission will be requested.
* If set to `false`, the global `read` permission will be revoked.
* If set to `Array<string | URL>`, the `read` permission will be requested with the
* specified file paths.
*
* Defaults to "inherit".
*/
read?: "inherit" | boolean | Array<string | URL>;

/** Specifies if the `run` permission should be requested or revoked.
* If set to `"inherit"`, the current `run` permission will be inherited.
* If set to `true`, the global `run` permission will be requested.
* If set to `false`, the global `run` permission will be revoked.
*
* Defaults to "inherit".
*/
run?: "inherit" | boolean | Array<string | URL>;

/** Specifies if the `write` permission should be requested or revoked.
* If set to `"inherit"`, the current `write` permission will be inherited.
* If set to `true`, the global `write` permission will be requested.
* If set to `false`, the global `write` permission will be revoked.
* If set to `Array<string | URL>`, the `write` permission will be requested with the
* specified file paths.
*
* Defaults to "inherit".
*/
write?: "inherit" | boolean | Array<string | URL>;
};
}

/** Register a bench which will be run when `deno bench` is used on the command
* line and the containing module looks like a bench module.
* `fn` can be async if required.
* ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({
* name: "example test",
* fn(): void {
* assertEquals("world", "world");
* },
* });
*
* Deno.bench({
* name: "example ignored test",
* ignore: Deno.build.os === "windows",
* fn(): void {
* // This test is ignored only on Windows machines
* },
* });
*
* Deno.bench({
* name: "example async test",
* async fn() {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* }
* });
* ```
*/
export function bench(t: BenchDefinition): void;

/** Register a bench which will be run when `deno bench` is used on the command
* line and the containing module looks like a bench module.
* `fn` can be async if required.
*
* ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench("My test description", (): void => {
* assertEquals("hello", "hello");
* });
*
* Deno.bench("My async test description", async (): Promise<void> => {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* });
* ```
*/
export function bench(
name: string,
fn: () => void | Promise<void>,
): void;

/** Register a bench which will be run when `deno bench` is used on the command
* line and the containing module looks like a bench module.
* `fn` can be async if required. Declared function must have a name.
*
* ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench(function myTestName(): void {
* assertEquals("hello", "hello");
* });
*
* Deno.bench(async function myOtherTestName(): Promise<void> {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* });
* ```
*/
export function bench(fn: () => void | Promise<void>): void;

/** Register a bench which will be run when `deno bench` is used on the command
* line and the containing module looks like a bench module.
* `fn` can be async if required.
*
* ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench("My test description", { permissions: { read: true } }, (): void => {
* assertEquals("hello", "hello");
* });
*
* Deno.bench("My async test description", { permissions: { read: false } }, async (): Promise<void> => {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* });
* ```
*/
export function bench(
name: string,
options: Omit<BenchDefinition, "fn" | "name">,
fn: () => void | Promise<void>,
): void;

/** Register a bench which will be run when `deno bench` is used on the command
* line and the containing module looks like a bench module.
* `fn` can be async if required.
*
* ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({ name: "My test description", permissions: { read: true } }, (): void => {
* assertEquals("hello", "hello");
* });
*
* Deno.bench({ name: "My async test description", permissions: { read: false } }, async (): Promise<void> => {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* });
* ```
*/
export function bench(
options: Omit<BenchDefinition, "fn">,
fn: () => void | Promise<void>,
): void;

/** Register a bench which will be run when `deno bench` is used on the command
* line and the containing module looks like a bench module.
* `fn` can be async if required. Declared function must have a name.
*
* ```ts
* import {assert, fail, assertEquals} from "https://deno.land/std/testing/asserts.ts";
*
* Deno.bench({ permissions: { read: true } }, function myTestName(): void {
* assertEquals("hello", "hello");
* });
*
* Deno.bench({ permissions: { read: false } }, async function myOtherTestName(): Promise<void> {
* const decoder = new TextDecoder("utf-8");
* const data = await Deno.readFile("hello_world.txt");
* assertEquals(decoder.decode(data), "Hello world");
* });
* ```
*/
export function bench(
options: Omit<BenchDefinition, "fn" | "name">,
fn: () => void | Promise<void>,
): void;

/**
* **UNSTABLE**: New API, yet to be vetted. This API is under consideration to
* determine if permissions are required to call it.
Expand Down