mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
[bun.js] Add Bun.nanoseconds() to report time in nanos
This commit is contained in:
18
integration/bunjs-only-snippets/performance.test.js
Normal file
18
integration/bunjs-only-snippets/performance.test.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { expect, it } from "bun:test";
|
||||
|
||||
it("performance.now() should be monotonic", () => {
|
||||
const first = performance.now();
|
||||
const second = performance.now();
|
||||
const third = performance.now();
|
||||
const fourth = performance.now();
|
||||
const fifth = performance.now();
|
||||
const sixth = performance.now();
|
||||
expect(first < second).toBe(true);
|
||||
expect(second < third).toBe(true);
|
||||
expect(third < fourth).toBe(true);
|
||||
expect(fourth < fifth).toBe(true);
|
||||
expect(fifth < sixth).toBe(true);
|
||||
expect(Bun.nanoseconds() > 0).toBe(true);
|
||||
expect(Bun.nanoseconds() > sixth).toBe(true);
|
||||
expect(typeof Bun.nanoseconds() === "number").toBe(true);
|
||||
});
|
||||
@@ -981,148 +981,121 @@ pub const Class = NewClass(
|
||||
},
|
||||
},
|
||||
},
|
||||
.{
|
||||
.match = .{
|
||||
.rfn = Router.match,
|
||||
.ts = Router.match_type_definition,
|
||||
.{ .match = .{
|
||||
.rfn = Router.match,
|
||||
.ts = Router.match_type_definition,
|
||||
}, .sleepSync = .{
|
||||
.rfn = sleepSync,
|
||||
}, .fetch = .{
|
||||
.rfn = Fetch.call,
|
||||
.ts = d.ts{},
|
||||
}, .getImportedStyles = .{
|
||||
.rfn = Bun.getImportedStyles,
|
||||
.ts = d.ts{
|
||||
.name = "getImportedStyles",
|
||||
.@"return" = "string[]",
|
||||
},
|
||||
|
||||
.sleepSync = .{
|
||||
.rfn = sleepSync,
|
||||
}, .inspect = .{
|
||||
.rfn = Bun.inspect,
|
||||
.ts = d.ts{
|
||||
.name = "inspect",
|
||||
.@"return" = "string",
|
||||
},
|
||||
.fetch = .{
|
||||
.rfn = Fetch.call,
|
||||
.ts = d.ts{},
|
||||
}, .getRouteFiles = .{
|
||||
.rfn = Bun.getRouteFiles,
|
||||
.ts = d.ts{
|
||||
.name = "getRouteFiles",
|
||||
.@"return" = "string[]",
|
||||
},
|
||||
.getImportedStyles = .{
|
||||
.rfn = Bun.getImportedStyles,
|
||||
.ts = d.ts{
|
||||
.name = "getImportedStyles",
|
||||
.@"return" = "string[]",
|
||||
},
|
||||
}, ._Path = .{
|
||||
.rfn = Bun.newPath,
|
||||
.ts = d.ts{},
|
||||
}, .getRouteNames = .{
|
||||
.rfn = Bun.getRouteNames,
|
||||
.ts = d.ts{
|
||||
.name = "getRouteNames",
|
||||
.@"return" = "string[]",
|
||||
},
|
||||
.inspect = .{
|
||||
.rfn = Bun.inspect,
|
||||
.ts = d.ts{
|
||||
.name = "inspect",
|
||||
.@"return" = "string",
|
||||
},
|
||||
}, .readFile = .{
|
||||
.rfn = Bun.readFileAsString,
|
||||
.ts = d.ts{
|
||||
.name = "readFile",
|
||||
.@"return" = "string",
|
||||
},
|
||||
.getRouteFiles = .{
|
||||
.rfn = Bun.getRouteFiles,
|
||||
.ts = d.ts{
|
||||
.name = "getRouteFiles",
|
||||
.@"return" = "string[]",
|
||||
},
|
||||
}, .resolveSync = .{
|
||||
.rfn = Bun.resolveSync,
|
||||
.ts = d.ts{
|
||||
.name = "resolveSync",
|
||||
.@"return" = "string",
|
||||
},
|
||||
._Path = .{
|
||||
.rfn = Bun.newPath,
|
||||
.ts = d.ts{},
|
||||
}, .resolve = .{
|
||||
.rfn = Bun.resolve,
|
||||
.ts = d.ts{
|
||||
.name = "resolve",
|
||||
.@"return" = "string",
|
||||
},
|
||||
.getRouteNames = .{
|
||||
.rfn = Bun.getRouteNames,
|
||||
.ts = d.ts{
|
||||
.name = "getRouteNames",
|
||||
.@"return" = "string[]",
|
||||
},
|
||||
}, .readFileBytes = .{
|
||||
.rfn = Bun.readFileAsBytes,
|
||||
.ts = d.ts{
|
||||
.name = "readFile",
|
||||
.@"return" = "Uint8Array",
|
||||
},
|
||||
.readFile = .{
|
||||
.rfn = Bun.readFileAsString,
|
||||
.ts = d.ts{
|
||||
.name = "readFile",
|
||||
.@"return" = "string",
|
||||
},
|
||||
}, .getPublicPath = .{
|
||||
.rfn = Bun.getPublicPathJS,
|
||||
.ts = d.ts{
|
||||
.name = "getPublicPath",
|
||||
.@"return" = "string",
|
||||
},
|
||||
.resolveSync = .{
|
||||
.rfn = Bun.resolveSync,
|
||||
.ts = d.ts{
|
||||
.name = "resolveSync",
|
||||
.@"return" = "string",
|
||||
},
|
||||
}, .registerMacro = .{
|
||||
.rfn = Bun.registerMacro,
|
||||
.ts = d.ts{
|
||||
.name = "registerMacro",
|
||||
.@"return" = "undefined",
|
||||
},
|
||||
.resolve = .{
|
||||
.rfn = Bun.resolve,
|
||||
.ts = d.ts{
|
||||
.name = "resolve",
|
||||
.@"return" = "string",
|
||||
},
|
||||
},
|
||||
.readFileBytes = .{
|
||||
.rfn = Bun.readFileAsBytes,
|
||||
.ts = d.ts{
|
||||
.name = "readFile",
|
||||
.@"return" = "Uint8Array",
|
||||
},
|
||||
},
|
||||
.getPublicPath = .{
|
||||
.rfn = Bun.getPublicPathJS,
|
||||
.ts = d.ts{
|
||||
.name = "getPublicPath",
|
||||
.@"return" = "string",
|
||||
},
|
||||
},
|
||||
.registerMacro = .{
|
||||
.rfn = Bun.registerMacro,
|
||||
.ts = d.ts{
|
||||
.name = "registerMacro",
|
||||
.@"return" = "undefined",
|
||||
},
|
||||
.enumerable = false,
|
||||
},
|
||||
.fs = .{
|
||||
.rfn = Bun.createNodeFS,
|
||||
.ts = d.ts{},
|
||||
.enumerable = false,
|
||||
},
|
||||
.jest = .{
|
||||
.rfn = @import("../test/jest.zig").Jest.call,
|
||||
.ts = d.ts{},
|
||||
.enumerable = false,
|
||||
},
|
||||
.gc = .{
|
||||
.rfn = Bun.runGC,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.allocUnsafe = .{
|
||||
.rfn = Bun.allocUnsafe,
|
||||
.ts = .{},
|
||||
},
|
||||
.mmap = .{
|
||||
.rfn = Bun.mmapFile,
|
||||
.ts = .{},
|
||||
},
|
||||
.generateHeapSnapshot = .{
|
||||
.rfn = Bun.generateHeapSnapshot,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.shrink = .{
|
||||
.rfn = Bun.shrink,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.openInEditor = .{
|
||||
.rfn = Bun.openInEditor,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.readAllStdinSync = .{
|
||||
.rfn = Bun.readAllStdinSync,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.serve = .{
|
||||
.rfn = Bun.serve,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.file = .{
|
||||
.rfn = JSC.WebCore.Blob.constructFile,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.write = .{
|
||||
.rfn = JSC.WebCore.Blob.writeFile,
|
||||
.ts = d.ts{},
|
||||
},
|
||||
.sha = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA512_256, "hash", false, false, true),
|
||||
},
|
||||
},
|
||||
.enumerable = false,
|
||||
}, .fs = .{
|
||||
.rfn = Bun.createNodeFS,
|
||||
.ts = d.ts{},
|
||||
.enumerable = false,
|
||||
}, .jest = .{
|
||||
.rfn = @import("../test/jest.zig").Jest.call,
|
||||
.ts = d.ts{},
|
||||
.enumerable = false,
|
||||
}, .gc = .{
|
||||
.rfn = Bun.runGC,
|
||||
.ts = d.ts{},
|
||||
}, .allocUnsafe = .{
|
||||
.rfn = Bun.allocUnsafe,
|
||||
.ts = .{},
|
||||
}, .mmap = .{
|
||||
.rfn = Bun.mmapFile,
|
||||
.ts = .{},
|
||||
}, .generateHeapSnapshot = .{
|
||||
.rfn = Bun.generateHeapSnapshot,
|
||||
.ts = d.ts{},
|
||||
}, .shrink = .{
|
||||
.rfn = Bun.shrink,
|
||||
.ts = d.ts{},
|
||||
}, .openInEditor = .{
|
||||
.rfn = Bun.openInEditor,
|
||||
.ts = d.ts{},
|
||||
}, .readAllStdinSync = .{
|
||||
.rfn = Bun.readAllStdinSync,
|
||||
.ts = d.ts{},
|
||||
}, .serve = .{
|
||||
.rfn = Bun.serve,
|
||||
.ts = d.ts{},
|
||||
}, .file = .{
|
||||
.rfn = JSC.WebCore.Blob.constructFile,
|
||||
.ts = d.ts{},
|
||||
}, .write = .{
|
||||
.rfn = JSC.WebCore.Blob.writeFile,
|
||||
.ts = d.ts{},
|
||||
}, .sha = .{
|
||||
.rfn = JSC.wrapWithHasContainer(Crypto.SHA512_256, "hash", false, false, true),
|
||||
}, .nanoseconds = .{
|
||||
.rfn = nanoseconds,
|
||||
} },
|
||||
.{
|
||||
.main = .{
|
||||
.get = getMain,
|
||||
@@ -1495,6 +1468,18 @@ pub const Crypto = struct {
|
||||
pub const MD5_SHA1 = CryptoHasher(Hashers.MD5_SHA1, "MD5_SHA1", "Bun_Crypto_MD5_SHA1");
|
||||
};
|
||||
|
||||
pub fn nanoseconds(
|
||||
_: void,
|
||||
_: JSC.C.JSContextRef,
|
||||
_: JSC.C.JSObjectRef,
|
||||
_: JSC.C.JSObjectRef,
|
||||
_: []const JSC.C.JSValueRef,
|
||||
_: JSC.C.ExceptionRef,
|
||||
) JSC.C.JSValueRef {
|
||||
const ns = JSC.VirtualMachine.vm.origin_timer.read();
|
||||
JSC.JSValue.jsNumberFromUint64(ns).asObjectRef();
|
||||
}
|
||||
|
||||
pub fn serve(
|
||||
_: void,
|
||||
ctx: js.JSContextRef,
|
||||
|
||||
12
types/bun/bun.d.ts
vendored
12
types/bun/bun.d.ts
vendored
@@ -807,6 +807,16 @@ declare module "bun" {
|
||||
edgeNames: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Nanoseconds since Bun.js was started as an integer.
|
||||
*
|
||||
* This uses a high-resolution monotonic system timer.
|
||||
*
|
||||
* After 14 weeks of consecutive uptime, this function
|
||||
* returns a `bigint` to prevent overflow
|
||||
*/
|
||||
export function nanoseconds(): number | bigint;
|
||||
|
||||
/**
|
||||
* Generate a heap snapshot for seeing where the heap is being used
|
||||
*/
|
||||
@@ -986,8 +996,6 @@ declare module "bun" {
|
||||
*/
|
||||
static readonly byteLength: 32;
|
||||
}
|
||||
|
||||
export const FFI: typeof import("bun:ffi");
|
||||
}
|
||||
|
||||
type TypedArray =
|
||||
|
||||
12
types/bun/globals.d.ts
vendored
12
types/bun/globals.d.ts
vendored
@@ -849,18 +849,6 @@ declare var performance: {
|
||||
*
|
||||
*/
|
||||
now: () => number;
|
||||
|
||||
/**
|
||||
* Nanoseconds since Bun.js started
|
||||
*
|
||||
* This is an integer up until approximately 14 weeks of uptime. After 14 weeks, it returns a `bigint` to account
|
||||
* for overflow.
|
||||
*
|
||||
* Uses a high-precision system timer to measure the time elapsed since the
|
||||
* Bun.js runtime was initialized. The value is monotonically increasing
|
||||
* during the lifetime of the runtime.
|
||||
*/
|
||||
nowNanoseconds: () => number | bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user