From 7e5e349b1387a968a96adb7ae22bcd9636c875c6 Mon Sep 17 00:00:00 2001 From: Felicio Mununga Date: Fri, 10 Feb 2023 20:55:43 +0100 Subject: [PATCH 1/8] add @bufbuild --- packages/protons-benchmark/package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/protons-benchmark/package.json b/packages/protons-benchmark/package.json index 167cd2e..e7e935e 100644 --- a/packages/protons-benchmark/package.json +++ b/packages/protons-benchmark/package.json @@ -70,6 +70,7 @@ "start:browser": "npx playwright-test dist/src/index.js --runner benchmark" }, "dependencies": { + "@bufbuild/protobuf": "^1.0.0", "@protobuf-ts/plugin": "^2.8.1", "@protobuf-ts/runtime": "^2.8.1", "@types/benchmark": "^2.1.1", @@ -82,5 +83,8 @@ "uint8arraylist": "^2.4.3", "uint8arrays": "^4.0.2" }, + "devDependencies": { + "@bufbuild/protoc-gen-es": "^1.0.0" + }, "private": true } From 25ea0c4ccb4d1da130f58a5a05b0cee9d1eb472a Mon Sep 17 00:00:00 2001 From: Felicio Mununga Date: Fri, 10 Feb 2023 21:05:26 +0100 Subject: [PATCH 2/8] add protobuf-es benchmark --- packages/protons-benchmark/buf.gen.yaml | 6 + packages/protons-benchmark/package.json | 3 +- packages/protons-benchmark/src/buf.yaml | 10 + packages/protons-benchmark/src/decode.ts | 4 + packages/protons-benchmark/src/encode.ts | 4 + packages/protons-benchmark/src/index.ts | 7 + .../src/protobuf-es/bench_pb.ts | 243 ++++++++++++++++++ 7 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 packages/protons-benchmark/buf.gen.yaml create mode 100644 packages/protons-benchmark/src/buf.yaml create mode 100644 packages/protons-benchmark/src/protobuf-es/bench_pb.ts diff --git a/packages/protons-benchmark/buf.gen.yaml b/packages/protons-benchmark/buf.gen.yaml new file mode 100644 index 0000000..c42ea5f --- /dev/null +++ b/packages/protons-benchmark/buf.gen.yaml @@ -0,0 +1,6 @@ +version: v1 +plugins: + - name: es + path: ../../node_modules/.bin/protoc-gen-es + opt: target=ts + out: ./src/protobuf-es diff --git a/packages/protons-benchmark/package.json b/packages/protons-benchmark/package.json index e7e935e..af7d650 100644 --- a/packages/protons-benchmark/package.json +++ b/packages/protons-benchmark/package.json @@ -57,7 +57,8 @@ "ignorePatterns": [ "src/pbjs/*", "src/protobuf-ts/*", - "src/protobufjs/*" + "src/protobufjs/*", + "src/protobuf-es/*" ] }, "scripts": { diff --git a/packages/protons-benchmark/src/buf.yaml b/packages/protons-benchmark/src/buf.yaml new file mode 100644 index 0000000..a258831 --- /dev/null +++ b/packages/protons-benchmark/src/buf.yaml @@ -0,0 +1,10 @@ +version: v1 +breaking: + use: + - FILE +lint: + use: + - DEFAULT + except: + - ENUM_ZERO_VALUE_SUFFIX + - ENUM_VALUE_PREFIX diff --git a/packages/protons-benchmark/src/decode.ts b/packages/protons-benchmark/src/decode.ts index cdd798d..9916d9e 100644 --- a/packages/protons-benchmark/src/decode.ts +++ b/packages/protons-benchmark/src/decode.ts @@ -10,6 +10,7 @@ import Benchmark from 'benchmark' import { decodeTest as pbjsDecodeTest } from './pbjs/bench.js' import { Test as ProtobufjsTest } from './protobufjs/bench.js' import { Test as ProtonsTest } from './protons/bench.js' +import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' const message = { meh: { @@ -37,6 +38,9 @@ new Benchmark.Suite() .add('protobufjs', () => { ProtobufjsTest.decode(buf) }) + .add('protobufes', () => { + ProtobufEsTest.fromBinary(buf) + }) .on('error', (err: Error) => { console.error(err) }) diff --git a/packages/protons-benchmark/src/encode.ts b/packages/protons-benchmark/src/encode.ts index 119a01a..88c406e 100644 --- a/packages/protons-benchmark/src/encode.ts +++ b/packages/protons-benchmark/src/encode.ts @@ -10,6 +10,7 @@ import Benchmark from 'benchmark' import { encodeTest as pbjsEncodeTest } from './pbjs/bench.js' import { Test as ProtobufjsTest } from './protobufjs/bench.js' import { Test as ProtonsTest } from './protons/bench.js' +import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' const message = { meh: { @@ -35,6 +36,9 @@ new Benchmark.Suite() .add('protobufjs', () => { ProtobufjsTest.encode(message).finish() }) + .add('protobufes', () => { + new ProtobufEsTest(message).toBinary() + }) .on('error', (err: Error) => { console.error(err) }) diff --git a/packages/protons-benchmark/src/index.ts b/packages/protons-benchmark/src/index.ts index 760d892..047a5f1 100644 --- a/packages/protons-benchmark/src/index.ts +++ b/packages/protons-benchmark/src/index.ts @@ -13,6 +13,7 @@ import { encodeTest as pbjsEncodeTest, decodeTest as pbjsDecodeTest } from './pb import { Test as ProtobufTsTest } from './protobuf-ts/bench.js' import { Test as ProtobufjsTest } from './protobufjs/bench.js' import { Test as ProtonsTest } from './protons/bench.js' +import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' const message = { meh: { @@ -61,6 +62,12 @@ new Benchmark.Suite() expectDecodedCorrectly(result) }) + .add('protobuf-es', () => { + const buf = new ProtobufEsTest(message).toBinary() + const result = ProtobufEsTest.fromBinary(buf) + + expectDecodedCorrectly(result) + }) .on('error', (err: Error) => { console.error(err) }) diff --git a/packages/protons-benchmark/src/protobuf-es/bench_pb.ts b/packages/protons-benchmark/src/protobuf-es/bench_pb.ts new file mode 100644 index 0000000..b9eec92 --- /dev/null +++ b/packages/protons-benchmark/src/protobuf-es/bench_pb.ts @@ -0,0 +1,243 @@ +// @generated by protoc-gen-es v1.0.0 with parameter "target=ts" +// @generated from file bench.proto (syntax proto3) +/* eslint-disable */ +// @ts-nocheck + +import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; +import { Message, proto3 } from "@bufbuild/protobuf"; + +/** + * @generated from enum FOO + */ +export enum FOO { + /** + * @generated from enum value: NONE = 0; + */ + NONE = 0, + + /** + * @generated from enum value: LOL = 1; + */ + LOL = 1, + + /** + * @generated from enum value: ABE = 3; + */ + ABE = 3, +} +// Retrieve enum metadata with: proto3.getEnumType(FOO) +proto3.util.setEnumType(FOO, "FOO", [ + { no: 0, name: "NONE" }, + { no: 1, name: "LOL" }, + { no: 3, name: "ABE" }, +]); + +/** + * @generated from message Foo + */ +export class Foo extends Message { + /** + * @generated from field: optional uint32 baz = 1; + */ + baz?: number; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime = proto3; + static readonly typeName = "Foo"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "baz", kind: "scalar", T: 13 /* ScalarType.UINT32 */, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): Foo { + return new Foo().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): Foo { + return new Foo().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): Foo { + return new Foo().fromJsonString(jsonString, options); + } + + static equals(a: Foo | PlainMessage | undefined, b: Foo | PlainMessage | undefined): boolean { + return proto3.util.equals(Foo, a, b); + } +} + +/** + * @generated from message Bar + */ +export class Bar extends Message { + /** + * @generated from field: optional Foo tmp = 1; + */ + tmp?: Foo; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime = proto3; + static readonly typeName = "Bar"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "tmp", kind: "message", T: Foo, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): Bar { + return new Bar().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): Bar { + return new Bar().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): Bar { + return new Bar().fromJsonString(jsonString, options); + } + + static equals(a: Bar | PlainMessage | undefined, b: Bar | PlainMessage | undefined): boolean { + return proto3.util.equals(Bar, a, b); + } +} + +/** + * @generated from message Yo + */ +export class Yo extends Message { + /** + * @generated from field: repeated FOO lol = 1; + */ + lol: FOO[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime = proto3; + static readonly typeName = "Yo"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "lol", kind: "enum", T: proto3.getEnumType(FOO), repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): Yo { + return new Yo().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): Yo { + return new Yo().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): Yo { + return new Yo().fromJsonString(jsonString, options); + } + + static equals(a: Yo | PlainMessage | undefined, b: Yo | PlainMessage | undefined): boolean { + return proto3.util.equals(Yo, a, b); + } +} + +/** + * @generated from message Lol + */ +export class Lol extends Message { + /** + * @generated from field: optional string lol = 1; + */ + lol?: string; + + /** + * @generated from field: Bar b = 2; + */ + b?: Bar; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime = proto3; + static readonly typeName = "Lol"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "lol", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 2, name: "b", kind: "message", T: Bar }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): Lol { + return new Lol().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): Lol { + return new Lol().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): Lol { + return new Lol().fromJsonString(jsonString, options); + } + + static equals(a: Lol | PlainMessage | undefined, b: Lol | PlainMessage | undefined): boolean { + return proto3.util.equals(Lol, a, b); + } +} + +/** + * @generated from message Test + */ +export class Test extends Message { + /** + * @generated from field: optional Lol meh = 6; + */ + meh?: Lol; + + /** + * @generated from field: optional uint32 hello = 3; + */ + hello?: number; + + /** + * @generated from field: optional string foo = 1; + */ + foo?: string; + + /** + * @generated from field: optional bytes payload = 7; + */ + payload?: Uint8Array; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime = proto3; + static readonly typeName = "Test"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 6, name: "meh", kind: "message", T: Lol, opt: true }, + { no: 3, name: "hello", kind: "scalar", T: 13 /* ScalarType.UINT32 */, opt: true }, + { no: 1, name: "foo", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 7, name: "payload", kind: "scalar", T: 12 /* ScalarType.BYTES */, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): Test { + return new Test().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): Test { + return new Test().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): Test { + return new Test().fromJsonString(jsonString, options); + } + + static equals(a: Test | PlainMessage | undefined, b: Test | PlainMessage | undefined): boolean { + return proto3.util.equals(Test, a, b); + } +} + From d498640d8e1c06b534bb88acacd831dfefd83b01 Mon Sep 17 00:00:00 2001 From: Felicio Mununga Date: Fri, 10 Feb 2023 21:31:24 +0100 Subject: [PATCH 3/8] update README.md --- packages/protons-benchmark/README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/protons-benchmark/README.md b/packages/protons-benchmark/README.md index 5f50673..5cfa1a8 100644 --- a/packages/protons-benchmark/README.md +++ b/packages/protons-benchmark/README.md @@ -29,7 +29,7 @@ $ cd packages/protons-benchmark ## Usage -Run the benchmark suite: +Run the benchmark suite in node: ```console $ npm start @@ -47,10 +47,11 @@ $ npm start > protons-benchmark@0.0.0 start > node dist/src/index.js -pbjs x 11,798 ops/sec ±4.58% (88 runs sampled) -protons x 11,693 ops/sec ±2.69% (85 runs sampled) -protobuf.js x 12,419 ops/sec ±1.66% (88 runs sampled) -@protobuf-ts x 10,536 ops/sec ±3.14% (85 runs sampled) +pbjs x 19,188 ops/sec ±0.38% (98 runs sampled) +protons x 19,001 ops/sec ±0.33% (95 runs sampled) +protobuf.js x 19,558 ops/sec ±0.30% (91 runs sampled) +@protobuf-ts x 17,216 ops/sec ±0.32% (95 runs sampled) +protobuf-es x 15,673 ops/sec ±0.48% (93 runs sampled) Fastest is protobuf.js ``` @@ -63,11 +64,12 @@ $ npm run start:browser > npx playwright-test dist/src/index.js --runner benchmark ✔ chromium set up -pbjs x 19,027 ops/sec ±0.86% (67 runs sampled) -protons x 18,901 ops/sec ±0.65% (67 runs sampled) -protobuf.js x 18,937 ops/sec ±0.55% (65 runs sampled) -@protobuf-ts x 16,669 ops/sec ±0.49% (68 runs sampled) -Fastest is pbjs,protobuf.js +pbjs x 19,763 ops/sec ±0.35% (67 runs sampled) +protons x 19,617 ops/sec ±0.37% (68 runs sampled) +protobuf.js x 19,772 ops/sec ±0.34% (67 runs sampled) +@protobuf-ts x 17,204 ops/sec ±0.33% (69 runs sampled) +protobuf-es x 16,032 ops/sec ±0.38% (68 runs sampled) +Fastest is protobuf.js,pbjs ``` ## License From f6307eb9c608ea4586336b1a454a8bed990202b3 Mon Sep 17 00:00:00 2001 From: Felicio Mununga Date: Fri, 10 Feb 2023 22:05:36 +0100 Subject: [PATCH 4/8] remove install step --- packages/protons-benchmark/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/protons-benchmark/README.md b/packages/protons-benchmark/README.md index 5cfa1a8..860274b 100644 --- a/packages/protons-benchmark/README.md +++ b/packages/protons-benchmark/README.md @@ -16,10 +16,6 @@ ## Install -```console -$ npm i protons-benchmark -``` - ```console $ git clone git@github.com:ipfs/protons.git $ cd protons From b7594a45a1a4d86ab05953eac35648accb8b0fb3 Mon Sep 17 00:00:00 2001 From: Felicio Mununga Date: Fri, 10 Feb 2023 22:05:54 +0100 Subject: [PATCH 5/8] add important build step --- packages/protons-benchmark/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/protons-benchmark/README.md b/packages/protons-benchmark/README.md index 860274b..bbf5f5e 100644 --- a/packages/protons-benchmark/README.md +++ b/packages/protons-benchmark/README.md @@ -20,6 +20,7 @@ $ git clone git@github.com:ipfs/protons.git $ cd protons $ npm i +$ npm run build $ cd packages/protons-benchmark ``` From 5b81e55df9661f633725ba516cf80d280af94e2a Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 13 Oct 2023 09:04:49 +0300 Subject: [PATCH 6/8] chore: fix linting --- packages/protons-benchmark/src/decode.ts | 2 +- packages/protons-benchmark/src/encode.ts | 2 +- packages/protons-benchmark/src/index.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/protons-benchmark/src/decode.ts b/packages/protons-benchmark/src/decode.ts index a9a59b5..f488733 100644 --- a/packages/protons-benchmark/src/decode.ts +++ b/packages/protons-benchmark/src/decode.ts @@ -7,9 +7,9 @@ $ npx playwright-test dist/src/index.js --runner benchmark import Benchmark from 'benchmark' import { decodeTest as pbjsDecodeTest } from './pbjs/bench.js' +import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' import { Test as ProtobufjsTest } from './protobufjs/bench.js' import { Test as ProtonsTest } from './protons/bench.js' -import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' const message = { meh: { diff --git a/packages/protons-benchmark/src/encode.ts b/packages/protons-benchmark/src/encode.ts index 19829c2..64c779d 100644 --- a/packages/protons-benchmark/src/encode.ts +++ b/packages/protons-benchmark/src/encode.ts @@ -7,9 +7,9 @@ $ npx playwright-test dist/src/index.js --runner benchmark import Benchmark from 'benchmark' import { encodeTest as pbjsEncodeTest } from './pbjs/bench.js' +import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' import { Test as ProtobufjsTest } from './protobufjs/bench.js' import { Test as ProtonsTest } from './protons/bench.js' -import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' const message = { meh: { diff --git a/packages/protons-benchmark/src/index.ts b/packages/protons-benchmark/src/index.ts index c9e6143..170a809 100644 --- a/packages/protons-benchmark/src/index.ts +++ b/packages/protons-benchmark/src/index.ts @@ -8,10 +8,10 @@ $ npx playwright-test dist/src/index.js --runner benchmark import { expect } from 'aegir/chai' import Benchmark from 'benchmark' import { encodeTest as pbjsEncodeTest, decodeTest as pbjsDecodeTest } from './pbjs/bench.js' +import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' import { Test as ProtobufTsTest } from './protobuf-ts/bench.js' import { Test as ProtobufjsTest } from './protobufjs/bench.js' import { Test as ProtonsTest } from './protons/bench.js' -import { Test as ProtobufEsTest } from './protobuf-es/bench_pb.js' const message = { meh: { From 84842e87237652e62ae317812b80aaca8aab9824 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 13 Oct 2023 09:08:22 +0300 Subject: [PATCH 7/8] chore: remove unused dev dep --- packages/protons-benchmark/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/protons-benchmark/package.json b/packages/protons-benchmark/package.json index 873e6a6..b43db41 100644 --- a/packages/protons-benchmark/package.json +++ b/packages/protons-benchmark/package.json @@ -61,8 +61,5 @@ "uint8arraylist": "^2.4.3", "uint8arrays": "^4.0.2" }, - "devDependencies": { - "@bufbuild/protoc-gen-es": "^1.0.0" - }, "private": true } From 4a6350839447ec209b80c7aa7165cf5b7eab8813 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 13 Oct 2023 09:09:26 +0300 Subject: [PATCH 8/8] chore: record protoc-gen-es version used --- packages/protons-benchmark/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/protons-benchmark/package.json b/packages/protons-benchmark/package.json index b43db41..738dfb2 100644 --- a/packages/protons-benchmark/package.json +++ b/packages/protons-benchmark/package.json @@ -41,7 +41,7 @@ "scripts": { "clean": "aegir clean", "lint": "aegir lint", - "dep-check": "aegir dep-check --ignore @protobuf-ts/plugin pbjs protons", + "dep-check": "aegir dep-check --ignore @protobuf-ts/plugin pbjs protons @bufbuild/protoc-gen-es", "build": "aegir build --no-bundle && cp -R src/protobufjs dist/src/protobufjs", "prestart": "npm run build", "start": "node dist/src/index.js", @@ -49,6 +49,7 @@ }, "dependencies": { "@bufbuild/protobuf": "^1.0.0", + "@bufbuild/protoc-gen-es": "^1.3.3", "@protobuf-ts/plugin": "^2.8.1", "@protobuf-ts/runtime": "^2.8.1", "@types/benchmark": "^2.1.1",