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

perf(cbor): decodeCbor & decodeCborSequence #6323

Merged
merged 2 commits into from
Jan 6, 2025

Conversation

BlackAsLight
Copy link
Contributor

This pull request rewrites the underlying code for decodeCbor and decodeCborSequence to offer more performance gains via less memory duplication and movement.

There is a caveat when decoding definite length Uint8Arrays in that they are being returned as a subarray; meaning their underling buffer Uint8Array.buffer is still the entire original input length and changes later to that input will be reflected in these returned Uint8Arrays.

Benchmark Source Code
  • std/cbor/deno.json
{
  "name": "@std/cbo",
  "version": "0.1.3",
  "exports": {
    ".": "./mod.ts",
    "./array-encoder-stream": "./array_encoder_stream.ts",
    "./byte-encoder-stream": "./byte_encoder_stream.ts",
    "./decode-cbor-sequence": "./decode_cbor_sequence.ts",
    "./decode-cbor": "./decode_cbor.ts",
    "./encode-cbor-sequence": "./encode_cbor_sequence.ts",
    "./encode-cbor": "./encode_cbor.ts",
    "./map-encoder-stream": "./map_encoder_stream.ts",
    "./sequence-decoder-stream": "./sequence_decoder_stream.ts",
    "./sequence-encoder-stream": "./sequence_encoder_stream.ts",
    "./tag": "./tag.ts",
    "./text-encoder-stream": "./text_encoder_stream.ts",
    "./types": "./types.ts"
  }
}
  • std/bench.ts
import { CborTag, decodeCbor as decodeCbor1, encodeCbor } from "jsr:@std/cbor";
import { decodeCbor as decodeCbor2 } from "jsr:@std/cbo";

function random(start: number, end: number): number {
  return Math.floor(Math.random() * (end - start) + start);
}

const Undefined = encodeCbor(undefined);
const Null = encodeCbor(null);
const Boolean = encodeCbor(!Math.floor(Math.random() * 2));
const Float = encodeCbor(Math.random() * 2 ** 8);
const Byte0 = encodeCbor(random(0, 24));
const Byte1 = encodeCbor(random(24, 2 ** 8));
const Byte2 = encodeCbor(random(2 ** 8, 2 ** 16));
const Byte4 = encodeCbor(random(2 ** 16, 2 ** 32));
const Byte8 = encodeCbor(random(2 ** 32, 2 ** 64));
const BigByte0 = encodeCbor(BigInt(random(0, 24)));
const BigByte1 = encodeCbor(BigInt(random(24, 2 ** 8)));
const BigByte2 = encodeCbor(BigInt(random(2 ** 8, 2 ** 16)));
const BigByte4 = encodeCbor(BigInt(random(2 ** 16, 2 ** 32)));
const BigByte8 = encodeCbor(BigInt(random(2 ** 32, 2 ** 64)));
const String0 = encodeCbor("a".repeat(random(0, 24)));
const String1 = encodeCbor("a".repeat(random(24, 2 ** 8)));
const String2 = encodeCbor("a".repeat(random(2 ** 8, 2 ** 16)));
const String4 = encodeCbor("a".repeat(random(2 ** 16, 2 ** 17)));
const Uint8Array0 = encodeCbor(new Uint8Array(random(0, 24)));
const Uint8Array1 = encodeCbor(new Uint8Array(random(24, 2 ** 8)));
const Uint8Array2 = encodeCbor(new Uint8Array(random(2 ** 8, 2 ** 16)));
const Uint8Array4 = encodeCbor(new Uint8Array(random(2 ** 16, 2 ** 32)));
const Uint8Array8 = encodeCbor(new Uint8Array(random(2 ** 32, 2 ** 33)));
const Now = encodeCbor(new Date());
const Tag = encodeCbor(new CborTag(3, random(0, 24)));

const Array0 = encodeCbor(new Array<number>(random(0, 24)).fill(0));
const Array1 = encodeCbor(new Array<number>(random(24, 2 ** 8)).fill(0));
const Array2 = encodeCbor(new Array<number>(random(2 ** 8, 2 ** 16)).fill(0));
const Array4 = encodeCbor(new Array<number>(random(2 ** 16, 2 ** 17)).fill(0));
const Object0 = encodeCbor(
  Object.fromEntries(
    new Array<number>(random(0, 24)).fill(0).map((_, i) => [i, i]),
  ),
);
const Object1 = encodeCbor(
  Object.fromEntries(
    new Array<number>(random(24, 2 ** 8)).fill(0).map((_, i) => [i, i]),
  ),
);
const Object2 = encodeCbor(
  Object.fromEntries(
    new Array<number>(random(2 ** 8, 2 ** 16)).fill(0).map((_, i) => [i, i]),
  ),
);
const Object4 = encodeCbor(
  Object.fromEntries(
    new Array<number>(random(2 ** 16, 2 ** 17)).fill(0).map((_, i) => [i, i]),
  ),
);
const Map0 = encodeCbor(
  new Map(new Array<number>(random(0, 24)).fill(0).map((_, i) => [i, i])),
);
const Map1 = encodeCbor(
  new Map(new Array<number>(random(24, 2 ** 8)).fill(0).map((_, i) => [i, i])),
);
const Map2 = encodeCbor(
  new Map(
    new Array<number>(random(2 ** 8, 2 ** 16)).fill(0).map((_, i) => [i, i]),
  ),
);
const Map4 = encodeCbor(
  new Map(
    new Array<number>(random(2 ** 16, 2 ** 17)).fill(0).map((_, i) => [i, i]),
  ),
);

Deno.bench({ name: "Current: Undefined", group: "Undefined" }, () => {
  decodeCbor1(Undefined);
});

Deno.bench({ name: "New: Undefined", group: "Undefined" }, () => {
  decodeCbor2(Undefined);
});

Deno.bench({ name: "Current: Null", group: "Null" }, () => {
  decodeCbor1(Null);
});

Deno.bench({ name: "New: Null", group: "Null" }, () => {
  decodeCbor2(Null);
});

Deno.bench({ name: "Current: Boolean", group: "Boolean" }, () => {
  decodeCbor1(Boolean);
});

Deno.bench({ name: "New: Boolean", group: "Boolean" }, () => {
  decodeCbor2(Boolean);
});

Deno.bench({ name: "Current: Float", group: "Float" }, () => {
  decodeCbor1(Float);
});

Deno.bench({ name: "New: Float", group: "Float" }, () => {
  decodeCbor2(Float);
});

Deno.bench({ name: "Current: Number0", group: "Number0" }, () => {
  decodeCbor1(Byte0);
});

Deno.bench({ name: "New: Number0", group: "Number0" }, () => {
  decodeCbor2(Byte0);
});

Deno.bench({ name: "Current: Number1", group: "Number1" }, () => {
  decodeCbor1(Byte1);
});

Deno.bench({ name: "New: Number1", group: "Number1" }, () => {
  decodeCbor2(Byte1);
});

Deno.bench({ name: "Current: Number2", group: "Number2" }, () => {
  decodeCbor1(Byte2);
});

Deno.bench({ name: "New: Number2", group: "Number2" }, () => {
  decodeCbor2(Byte2);
});

Deno.bench({ name: "Current: Number4", group: "Number4" }, () => {
  decodeCbor1(Byte4);
});

Deno.bench({ name: "New: Number4", group: "Number4" }, () => {
  decodeCbor2(Byte4);
});

Deno.bench({ name: "Current: Number8", group: "Number8" }, () => {
  decodeCbor1(Byte8);
});

Deno.bench({ name: "New: Number8", group: "Number8" }, () => {
  decodeCbor2(Byte8);
});

Deno.bench({ name: "Current: BigInt0", group: "BigInt0" }, () => {
  decodeCbor1(BigByte0);
});

Deno.bench({ name: "New: BigInt0", group: "BigInt0" }, () => {
  decodeCbor2(BigByte0);
});

Deno.bench({ name: "Current: BigInt1", group: "BigInt1" }, () => {
  decodeCbor1(BigByte1);
});

Deno.bench({ name: "New: BigInt1", group: "BigInt1" }, () => {
  decodeCbor2(BigByte1);
});

Deno.bench({ name: "Current: BigInt2", group: "BigInt2" }, () => {
  decodeCbor1(BigByte2);
});

Deno.bench({ name: "New: BigInt2", group: "BigInt2" }, () => {
  decodeCbor2(BigByte2);
});

Deno.bench({ name: "Current: BigInt4", group: "BigInt4" }, () => {
  decodeCbor1(BigByte4);
});

Deno.bench({ name: "New: BigInt4", group: "BigInt4" }, () => {
  decodeCbor2(BigByte4);
});

Deno.bench({ name: "Current: BigInt8", group: "BigInt8" }, () => {
  decodeCbor1(BigByte8);
});

Deno.bench({ name: "New: BigInt8", group: "BigInt8" }, () => {
  decodeCbor2(BigByte8);
});

Deno.bench({ name: "Current: String0", group: "String0" }, () => {
  decodeCbor1(String0);
});

Deno.bench({ name: "New: String0", group: "String0" }, () => {
  decodeCbor2(String0);
});

Deno.bench({ name: "Current: String1", group: "String1" }, () => {
  decodeCbor1(String1);
});

Deno.bench({ name: "New: String1", group: "String1" }, () => {
  decodeCbor2(String1);
});

Deno.bench({ name: "Current: String2", group: "String2" }, () => {
  decodeCbor1(String2);
});

Deno.bench({ name: "New: String2", group: "String2" }, () => {
  decodeCbor2(String2);
});

Deno.bench({ name: "Current: String4", group: "String4" }, () => {
  decodeCbor1(String4);
});

Deno.bench({ name: "New: String4", group: "String4" }, () => {
  decodeCbor2(String4);
});

Deno.bench({ name: "Current: Uint8Array0", group: "Uint8Array0" }, () => {
  decodeCbor1(Uint8Array0);
});

Deno.bench({ name: "New: Uint8Array0", group: "Uint8Array0" }, () => {
  decodeCbor2(Uint8Array0);
});

Deno.bench({ name: "Current: Uint8Array1", group: "Uint8Array1" }, () => {
  decodeCbor1(Uint8Array1);
});

Deno.bench({ name: "New: Uint8Array1", group: "Uint8Array1" }, () => {
  decodeCbor2(Uint8Array1);
});

Deno.bench({ name: "Current: Uint8Array2", group: "Uint8Array2" }, () => {
  decodeCbor1(Uint8Array2);
});

Deno.bench({ name: "New: Uint8Array2", group: "Uint8Array2" }, () => {
  decodeCbor2(Uint8Array2);
});

// Deno.bench({ name: "Current: Uint8Array4", group: "Uint8Array4" }, () => {
//   decodeCbor1(Uint8Array4);
// });

Deno.bench({ name: "New: Uint8Array4", group: "Uint8Array4" }, () => {
  decodeCbor2(Uint8Array4);
});

// Deno.bench({ name: "Current: Uint8Array8", group: "Uint8Array8" }, () => {
//   decodeCbor1(Uint8Array8);
// });

Deno.bench({ name: "New: Uint8Array8", group: "Uint8Array8" }, () => {
  decodeCbor2(Uint8Array8);
});

Deno.bench({ name: "Current: Date", group: "Date" }, () => {
  decodeCbor1(Now);
});

Deno.bench({ name: "New: Date", group: "Date" }, () => {
  decodeCbor2(Now);
});

Deno.bench({ name: "Current: CborTag", group: "CborTag" }, () => {
  decodeCbor1(Tag);
});

Deno.bench({ name: "New: CborTag", group: "CborTag" }, () => {
  decodeCbor2(Tag);
});

Deno.bench({ name: "Current: Array0", group: "Array0" }, () => {
  decodeCbor1(Array0);
});

Deno.bench({ name: "New: Array0", group: "Array0" }, () => {
  decodeCbor2(Array0);
});

Deno.bench({ name: "Current: Array1", group: "Array1" }, () => {
  decodeCbor1(Array1);
});

Deno.bench({ name: "New: Array1", group: "Array1" }, () => {
  decodeCbor2(Array1);
});

Deno.bench({ name: "Current: Array2", group: "Array2" }, () => {
  decodeCbor1(Array2);
});

Deno.bench({ name: "New: Array2", group: "Array2" }, () => {
  decodeCbor2(Array2);
});

Deno.bench({ name: "Current: Array4", group: "Array4" }, () => {
  decodeCbor1(Array4);
});

Deno.bench({ name: "New: Array4", group: "Array4" }, () => {
  decodeCbor2(Array4);
});

Deno.bench({ name: "Current: Object0", group: "Object0" }, () => {
  decodeCbor1(Object0);
});

Deno.bench({ name: "New: Object0", group: "Object0" }, () => {
  decodeCbor2(Object0);
});

Deno.bench({ name: "Current: Object1", group: "Object1" }, () => {
  decodeCbor1(Object1);
});

Deno.bench({ name: "New: Object1", group: "Object1" }, () => {
  decodeCbor2(Object1);
});

Deno.bench({ name: "Current: Object2", group: "Object2" }, () => {
  decodeCbor1(Object2);
});

Deno.bench({ name: "New: Object2", group: "Object2" }, () => {
  decodeCbor2(Object2);
});

Deno.bench({ name: "Current: Object4", group: "Object4" }, () => {
  decodeCbor1(Object4);
});

Deno.bench({ name: "New: Object4", group: "Object4" }, () => {
  decodeCbor2(Object4);
});

Deno.bench({ name: "Current: Map0", group: "Map0" }, () => {
  decodeCbor1(Map0);
});

Deno.bench({ name: "New: Map0", group: "Map0" }, () => {
  decodeCbor2(Map0);
});

Deno.bench({ name: "Current: Map1", group: "Map1" }, () => {
  decodeCbor1(Map1);
});

Deno.bench({ name: "New: Map1", group: "Map1" }, () => {
  decodeCbor2(Map1);
});

Deno.bench({ name: "Current: Map2", group: "Map2" }, () => {
  decodeCbor1(Map2);
});

Deno.bench({ name: "New: Map2", group: "Map2" }, () => {
  decodeCbor2(Map2);
});

Deno.bench({ name: "Current: Map4", group: "Map4" }, () => {
  decodeCbor1(Map4);
});

Deno.bench({ name: "New: Map4", group: "Map4" }, () => {
  decodeCbor2(Map4);
});
Benchmark Results
Check file:///Users/soul/Projects/std/bench.ts
    CPU | Apple M1
Runtime | Deno 2.1.4 (aarch64-apple-darwin)

file:///Users/soul/Projects/std/bench.ts

benchmark              time/iter (avg)        iter/s      (min … max)           p75      p99     p995
---------------------- ----------------------------- --------------------- --------------------------

group Undefined
Current: Undefined            178.9 ns     5,590,000 (151.9 ns … 500.2 ns) 162.0 ns 450.9 ns 473.4 ns
New: Undefined                  6.6 ns   151,400,000 (  5.6 ns … 101.6 ns)   5.9 ns  21.6 ns  25.4 ns

summary
  New: Undefined
    27.09x faster than Current: Undefined

group Null
Current: Null                 180.1 ns     5,553,000 (151.7 ns … 480.2 ns) 162.0 ns 437.2 ns 462.5 ns
New: Null                      12.9 ns    77,780,000 (  7.6 ns …  91.3 ns)  16.7 ns  51.0 ns  61.1 ns

summary
  New: Null
    14.01x faster than Current: Null

group Boolean
Current: Boolean              188.9 ns     5,292,000 (151.6 ns … 512.6 ns) 165.1 ns 478.6 ns 498.9 ns
New: Boolean                   12.4 ns    80,630,000 (  7.6 ns … 120.7 ns)   8.6 ns  47.3 ns  58.5 ns

summary
  New: Boolean
    15.23x faster than Current: Boolean

group Float
Current: Float                880.7 ns     1,135,000 (673.5 ns …   1.6 µs) 949.2 ns   1.6 µs   1.6 µs
New: Float                    143.3 ns     6,979,000 (122.8 ns … 484.1 ns) 126.4 ns 368.1 ns 405.1 ns

summary
  New: Float
     6.15x faster than Current: Float

group Number0
Current: Number0              183.0 ns     5,464,000 (151.5 ns … 583.1 ns) 169.6 ns 509.4 ns 546.5 ns
New: Number0                   15.7 ns    63,610,000 ( 10.2 ns … 133.0 ns)  11.1 ns  59.4 ns  68.1 ns

summary
  New: Number0
    11.64x faster than Current: Number0

group Number1
Current: Number1              588.1 ns     1,700,000 (458.9 ns …   1.3 µs) 607.4 ns   1.3 µs   1.3 µs
New: Number1                  102.4 ns     9,764,000 ( 80.8 ns … 312.9 ns)  85.1 ns 285.8 ns 299.2 ns

summary
  New: Number1
     5.74x faster than Current: Number1

group Number2
Current: Number2              599.2 ns     1,669,000 (478.4 ns …   1.2 µs) 633.6 ns   1.2 µs   1.2 µs
New: Number2                   98.8 ns    10,130,000 ( 81.7 ns … 303.3 ns)  84.9 ns 244.6 ns 262.2 ns

summary
  New: Number2
     6.07x faster than Current: Number2

group Number4
Current: Number4              723.4 ns     1,382,000 (525.5 ns …   1.6 µs) 809.2 ns   1.6 µs   1.6 µs
New: Number4                  101.0 ns     9,900,000 ( 79.3 ns … 292.7 ns)  84.0 ns 251.4 ns 269.1 ns

summary
  New: Number4
     7.16x faster than Current: Number4

group Number8
Current: Number8              879.9 ns     1,136,000 (684.3 ns …   1.5 µs) 955.0 ns   1.5 µs   1.5 µs
New: Number8                  101.0 ns     9,901,000 ( 80.4 ns … 321.0 ns)  84.7 ns 242.5 ns 273.0 ns

summary
  New: Number8
     8.71x faster than Current: Number8

group BigInt0
Current: BigInt0              186.6 ns     5,360,000 (151.1 ns … 493.3 ns) 166.4 ns 459.1 ns 491.5 ns
New: BigInt0                   16.6 ns    60,330,000 ( 10.7 ns … 133.9 ns)  11.7 ns  59.5 ns  68.2 ns

summary
  New: BigInt0
    11.26x faster than Current: BigInt0

group BigInt1
Current: BigInt1              585.5 ns     1,708,000 (460.5 ns …   1.3 µs) 610.7 ns   1.3 µs   1.3 µs
New: BigInt1                  103.9 ns     9,621,000 ( 81.7 ns … 396.6 ns)  86.5 ns 272.0 ns 278.9 ns

summary
  New: BigInt1
     5.63x faster than Current: BigInt1

group BigInt2
Current: BigInt2              645.1 ns     1,550,000 (479.2 ns …   1.5 µs) 744.6 ns   1.5 µs   1.5 µs
New: BigInt2                  101.0 ns     9,903,000 ( 82.6 ns … 322.1 ns)  85.3 ns 256.9 ns 286.1 ns

summary
  New: BigInt2
     6.39x faster than Current: BigInt2

group BigInt4
Current: BigInt4              807.7 ns     1,238,000 (527.8 ns …   1.8 µs) 956.1 ns   1.8 µs   1.8 µs
New: BigInt4                  109.8 ns     9,107,000 ( 82.0 ns … 429.4 ns) 102.2 ns 285.9 ns 304.0 ns

summary
  New: BigInt4
     7.36x faster than Current: BigInt4

group BigInt8
Current: BigInt8                1.2 µs       847,400 (681.3 ns …   3.0 µs)   1.4 µs   3.0 µs   3.0 µs
New: BigInt8                  163.1 ns     6,132,000 ( 85.2 ns … 440.5 ns) 208.5 ns 310.0 ns 330.4 ns

summary
  New: BigInt8
     7.24x faster than Current: BigInt8

group String0
Current: String0                2.4 µs       411,800 (  1.5 µs …   4.3 µs)   2.7 µs   4.3 µs   4.3 µs
New: String0                    1.3 µs       770,700 (911.7 ns …   2.2 µs)   1.5 µs   2.2 µs   2.2 µs

summary
  New: String0
     1.87x faster than Current: String0

group String1
Current: String1                7.3 µs       136,100 (  6.1 µs …  10.1 µs)   7.9 µs  10.1 µs  10.1 µs
New: String1                    1.4 µs       692,700 (988.8 ns …   6.4 µs)   1.5 µs   6.4 µs   6.4 µs

summary
  New: String1
     5.09x faster than Current: String1

group String2
Current: String2              241.9 µs         4,134 (145.1 µs …   1.8 ms) 356.1 µs 822.8 µs 918.0 µs
New: String2                    2.9 µs       340,000 (  1.9 µs …   4.1 µs)   3.4 µs   4.1 µs   4.1 µs

summary
  New: String2
    82.25x faster than Current: String2

group String4
Current: String4                3.0 ms         333.8 (  1.9 ms …   6.7 ms)   3.5 ms   6.6 ms   6.7 ms
New: String4                   15.7 µs        63,630 (  7.3 µs … 846.9 µs)  22.4 µs 110.8 µs 206.0 µs

summary
  New: String4
   190.60x faster than Current: String4

group Uint8Array0
Current: Uint8Array0          974.8 ns     1,026,000 (724.9 ns …   1.7 µs)   1.1 µs   1.7 µs   1.7 µs
New: Uint8Array0               64.4 ns    15,540,000 ( 49.1 ns … 181.8 ns)  60.5 ns 153.8 ns 174.8 ns

summary
  New: Uint8Array0
    15.15x faster than Current: Uint8Array0

group Uint8Array1
Current: Uint8Array1            6.3 µs       157,600 (  5.1 µs …   7.6 µs)   6.8 µs   7.6 µs   7.6 µs
New: Uint8Array1              142.7 ns     7,009,000 (114.5 ns … 412.2 ns) 135.2 ns 352.8 ns 389.8 ns

summary
  New: Uint8Array1
    44.48x faster than Current: Uint8Array1

group Uint8Array2
Current: Uint8Array2          674.9 µs         1,482 (433.1 µs …   2.7 ms) 631.3 µs   2.2 ms   2.5 ms
New: Uint8Array2              160.6 ns     6,228,000 (114.9 ns … 437.0 ns) 173.8 ns 400.2 ns 417.9 ns

summary
  New: Uint8Array2
     4203x faster than Current: Uint8Array2

group Uint8Array4
New: Uint8Array4              160.9 ns     6,216,000 (114.9 ns … 905.0 ns) 153.6 ns 407.5 ns 460.0 ns

group Uint8Array8
New: Uint8Array8              205.3 ns     4,870,000 (144.2 ns … 485.3 ns) 234.2 ns 459.9 ns 468.4 ns

group Date
Current: Date                   1.1 µs       942,200 (778.7 ns …   1.6 µs)   1.2 µs   1.6 µs   1.6 µs
New: Date                     184.8 ns     5,413,000 (137.8 ns … 467.0 ns) 198.4 ns 425.7 ns 441.6 ns

summary
  New: Date
     5.74x faster than Current: Date

group CborTag
Current: CborTag              242.0 ns     4,133,000 (187.6 ns … 631.1 ns) 254.5 ns 621.1 ns 625.0 ns
New: CborTag                   54.5 ns    18,340,000 ( 32.8 ns … 173.8 ns)  80.7 ns 145.8 ns 156.2 ns

summary
  New: CborTag
     4.44x faster than Current: CborTag

group Array0
Current: Array0               564.5 ns     1,772,000 (422.8 ns …   1.3 µs) 657.1 ns   1.3 µs   1.3 µs
New: Array0                   202.2 ns     4,945,000 (111.4 ns … 469.8 ns) 270.6 ns 461.0 ns 463.0 ns

summary
  New: Array0
     2.79x faster than Current: Array0

group Array1
Current: Array1                 6.2 µs       161,300 (  4.1 µs … 875.8 µs)   4.6 µs  15.8 µs  34.0 µs
New: Array1                     2.3 µs       436,800 (  1.7 µs …   3.7 µs)   2.6 µs   3.7 µs   3.7 µs

summary
  New: Array1
     2.71x faster than Current: Array1

group Array2
Current: Array2               246.4 µs         4,058 (190.5 µs …   1.6 ms) 203.1 µs 800.0 µs 920.9 µs
New: Array2                   105.7 µs         9,464 ( 61.0 µs …   1.7 ms) 163.7 µs 467.7 µs 609.0 µs

summary
  New: Array2
     2.33x faster than Current: Array2

group Array4
Current: Array4                 3.6 ms         275.1 (  2.4 ms …   8.9 ms)   4.2 ms   8.0 ms   8.9 ms
New: Array4                     1.6 ms         612.3 (924.7 µs …   5.5 ms)   2.2 ms   3.7 ms   4.0 ms

summary
  New: Array4
     2.23x faster than Current: Array4

group Object0
Current: Object0                7.9 µs       126,600 (  6.8 µs …   9.4 µs)   8.5 µs   9.4 µs   9.4 µs
New: Object0                    5.9 µs       169,700 (  5.0 µs …   7.1 µs)   6.6 µs   7.1 µs   7.1 µs

summary
  New: Object0
     1.34x faster than Current: Object0

group Object1
Current: Object1              402.4 µs         2,485 (272.9 µs …   5.8 ms) 300.9 µs   1.2 ms   1.3 ms
New: Object1                  241.9 µs         4,135 (178.0 µs …   1.7 ms) 186.9 µs 846.4 µs 974.4 µs

summary
  New: Object1
     1.66x faster than Current: Object1

group Object2
Current: Object2               52.0 ms          19.2 ( 41.4 ms …  63.7 ms)  58.8 ms  63.7 ms  63.7 ms
New: Object2                   27.2 ms          36.8 ( 22.4 ms …  33.9 ms)  29.8 ms  33.9 ms  33.9 ms

summary
  New: Object2
     1.92x faster than Current: Object2

group Object4
Current: Object4              312.7 ms           3.2 (260.0 ms … 466.9 ms) 316.0 ms 466.9 ms 466.9 ms
New: Object4                  189.8 ms           5.3 (141.7 ms … 237.1 ms) 206.7 ms 237.1 ms 237.1 ms

summary
  New: Object4
     1.65x faster than Current: Object4

group Map0
Current: Map0                   1.3 µs       778,900 (972.6 ns …   2.2 µs)   1.5 µs   2.2 µs   2.2 µs
New: Map0                     517.9 ns     1,931,000 (353.6 ns …   1.2 µs) 576.1 ns   1.2 µs   1.2 µs

summary
  New: Map0
     2.48x faster than Current: Map0

group Map1
Current: Map1                  10.5 µs        94,830 (  6.1 µs …   3.2 ms)   8.2 µs  35.2 µs  64.4 µs
New: Map1                       2.9 µs       342,600 (  2.3 µs …   3.8 µs)   3.2 µs   3.8 µs   3.8 µs

summary
  New: Map1
     3.61x faster than Current: Map1

group Map2
Current: Map2                  45.4 ms          22.0 ( 35.6 ms …  71.9 ms)  49.3 ms  71.9 ms  71.9 ms
New: Map2                       9.9 ms         101.0 (  7.9 ms …  23.3 ms)  10.3 ms  23.3 ms  23.3 ms

summary
  New: Map2
     4.59x faster than Current: Map2

group Map4
Current: Map4                  88.2 ms          11.3 ( 67.3 ms … 132.0 ms)  94.7 ms 132.0 ms 132.0 ms
New: Map4                      21.2 ms          47.3 ( 15.6 ms …  32.6 ms)  23.3 ms  32.6 ms  32.6 ms

summary
  New: Map4
     4.17x faster than Current: Map4

@BlackAsLight BlackAsLight requested a review from kt3k as a code owner January 1, 2025 11:53
@github-actions github-actions bot added the cbor label Jan 1, 2025
Copy link

codecov bot commented Jan 1, 2025

Codecov Report

Attention: Patch coverage is 93.45794% with 14 lines in your changes missing coverage. Please review.

Project coverage is 96.34%. Comparing base (e3dc30a) to head (29a1e48).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
cbor/_common_decode.ts 93.13% 14 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6323      +/-   ##
==========================================
- Coverage   96.35%   96.34%   -0.01%     
==========================================
  Files         547      547              
  Lines       41671    41723      +52     
  Branches     6315     6322       +7     
==========================================
+ Hits        40151    40199      +48     
- Misses       1479     1483       +4     
  Partials       41       41              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The numbers of the perf gains look very impressive 👍

Thanks for the contribution! LGTM

@kt3k kt3k merged commit 4cb81d7 into denoland:main Jan 6, 2025
18 checks passed
@BlackAsLight BlackAsLight deleted the cbor_decoding_performance branch January 6, 2025 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants