|
13 | 13 | // limitations under the License.
|
14 | 14 |
|
15 | 15 | import Benchmark from "benchmark";
|
16 |
| -import { create, fromBinary, toBinary, protoInt64 } from "@bufbuild/protobuf"; |
| 16 | +import { |
| 17 | + create, |
| 18 | + fromBinary, |
| 19 | + toBinary, |
| 20 | + protoInt64, |
| 21 | + toJsonString, |
| 22 | + fromJsonString, |
| 23 | +} from "@bufbuild/protobuf"; |
17 | 24 | import { readFileSync } from "fs";
|
18 | 25 | import { UserSchema } from "./gen/ts/extra/example_pb.js";
|
19 | 26 | import {
|
@@ -95,173 +102,163 @@ interface Test {
|
95 | 102 | }
|
96 | 103 |
|
97 | 104 | function setupTests(): Test[] {
|
98 |
| - const tests: Test[] = []; |
99 |
| - { |
100 |
| - const bytes = readFileSync( |
101 |
| - new URL("perf-payload.bin", import.meta.url).pathname, |
102 |
| - ); |
103 |
| - tests.push({ |
104 |
| - name: `fromBinary perf-payload.bin`, |
105 |
| - fn: () => { |
106 |
| - fromBinary(PerfMessageSchema, bytes); |
107 |
| - }, |
108 |
| - }); |
109 |
| - } |
110 |
| - { |
111 |
| - const desc = UserSchema; |
112 |
| - const tinyUser = create(desc, { |
113 |
| - active: false, |
114 |
| - manager: { active: true }, |
115 |
| - }); |
116 |
| - const data = toBinary(desc, tinyUser); |
117 |
| - tests.push({ |
118 |
| - name: `fromBinary tiny example.User (${data.byteLength} bytes)`, |
119 |
| - fn: () => { |
120 |
| - fromBinary(desc, data); |
121 |
| - }, |
122 |
| - }); |
123 |
| - } |
124 |
| - { |
125 |
| - const desc = UserSchema; |
126 |
| - const normalUser = create(desc, { |
127 |
| - firstName: "Jane", |
128 |
| - lastName: "Doe", |
129 |
| - active: true, |
130 |
| - manager: { firstName: "Jane", lastName: "Doe", active: false }, |
131 |
| - locations: ["Seattle", "New York", "Tokyo"], |
132 |
| - projects: { foo: "project foo", bar: "project bar" }, |
133 |
| - }); |
134 |
| - const data = toBinary(desc, normalUser); |
135 |
| - tests.push({ |
136 |
| - name: `fromBinary normal example.User (${data.byteLength} bytes)`, |
137 |
| - fn: () => { |
138 |
| - fromBinary(desc, data); |
139 |
| - }, |
140 |
| - }); |
141 |
| - } |
142 |
| - { |
143 |
| - const desc = ScalarValuesMessageSchema; |
144 |
| - const message = create(ScalarValuesMessageSchema, { |
145 |
| - doubleField: 0.75, |
146 |
| - floatField: -0.75, |
147 |
| - int64Field: protoInt64.parse(-1), |
148 |
| - uint64Field: protoInt64.uParse(1), |
149 |
| - int32Field: -123, |
150 |
| - fixed64Field: protoInt64.uParse(1), |
151 |
| - fixed32Field: 123, |
152 |
| - boolField: true, |
153 |
| - stringField: "hello world", |
154 |
| - bytesField: new Uint8Array([ |
155 |
| - 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, |
156 |
| - ]), |
157 |
| - uint32Field: 123, |
158 |
| - sfixed32Field: -123, |
159 |
| - sfixed64Field: protoInt64.parse(-1), |
160 |
| - sint32Field: -1, |
161 |
| - sint64Field: protoInt64.parse(-1), |
162 |
| - }); |
163 |
| - const data = toBinary(desc, message); |
164 |
| - tests.push({ |
165 |
| - name: `fromBinary scalar values (${data.byteLength} bytes)`, |
166 |
| - fn: () => { |
167 |
| - fromBinary(desc, data); |
168 |
| - }, |
169 |
| - }); |
170 |
| - } |
171 |
| - { |
172 |
| - const desc = RepeatedScalarValuesMessageSchema; |
173 |
| - const message = create(desc, { |
174 |
| - doubleField: [0.75, 0, 1], |
175 |
| - floatField: [0.75, -0.75], |
176 |
| - int64Field: [protoInt64.parse(-1), protoInt64.parse(-2)], |
177 |
| - uint64Field: [protoInt64.uParse(1), protoInt64.uParse(2)], |
178 |
| - int32Field: [-123, 500], |
179 |
| - fixed64Field: [protoInt64.uParse(1), protoInt64.uParse(99)], |
180 |
| - fixed32Field: [123, 999], |
181 |
| - boolField: [true, false, true], |
182 |
| - stringField: ["hello", "world"], |
183 |
| - bytesField: [ |
184 |
| - new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]), |
185 |
| - ], |
186 |
| - uint32Field: [123, 123], |
187 |
| - sfixed32Field: [-123, -123, -123], |
188 |
| - sfixed64Field: [ |
189 |
| - protoInt64.parse(-1), |
190 |
| - protoInt64.parse(-2), |
191 |
| - protoInt64.parse(100), |
192 |
| - ], |
193 |
| - sint32Field: [-1, -2, 999], |
194 |
| - sint64Field: [ |
195 |
| - protoInt64.parse(-1), |
196 |
| - protoInt64.parse(-99), |
197 |
| - protoInt64.parse(99), |
198 |
| - ], |
199 |
| - }); |
200 |
| - const data = toBinary(desc, message); |
201 |
| - tests.push({ |
202 |
| - name: `fromBinary repeated scalar fields (${data.byteLength} bytes)`, |
203 |
| - fn: () => { |
204 |
| - fromBinary(desc, data); |
205 |
| - }, |
206 |
| - }); |
207 |
| - } |
208 |
| - { |
209 |
| - const desc = MapsMessageSchema; |
210 |
| - const message = create(desc, { |
211 |
| - strStrField: { a: "str", b: "xx" }, |
212 |
| - strInt32Field: { a: 123, b: 455 }, |
213 |
| - strInt64Field: { a: protoInt64.parse(123) }, |
214 |
| - strBoolField: { a: true, b: false }, |
215 |
| - strBytesField: { |
216 |
| - a: new Uint8Array([ |
| 105 | + const tests: Test[] = [ |
| 106 | + { |
| 107 | + name: "perf-payload.bin", |
| 108 | + desc: PerfMessageSchema, |
| 109 | + msg: fromBinary( |
| 110 | + PerfMessageSchema, |
| 111 | + readFileSync(new URL("perf-payload.bin", import.meta.url).pathname), |
| 112 | + ), |
| 113 | + }, |
| 114 | + { |
| 115 | + name: "tiny example.User", |
| 116 | + desc: UserSchema, |
| 117 | + msg: create(UserSchema, { active: false, manager: { active: true } }), |
| 118 | + }, |
| 119 | + { |
| 120 | + name: "normal example.User", |
| 121 | + desc: UserSchema, |
| 122 | + msg: create(UserSchema, { |
| 123 | + firstName: "Jane", |
| 124 | + lastName: "Doe", |
| 125 | + active: true, |
| 126 | + manager: { firstName: "Jane", lastName: "Doe", active: false }, |
| 127 | + locations: ["Seattle", "New York", "Tokyo"], |
| 128 | + projects: { foo: "project foo", bar: "project bar" }, |
| 129 | + }), |
| 130 | + }, |
| 131 | + { |
| 132 | + name: "scalar values", |
| 133 | + desc: ScalarValuesMessageSchema, |
| 134 | + msg: create(ScalarValuesMessageSchema, { |
| 135 | + doubleField: 0.75, |
| 136 | + floatField: -0.75, |
| 137 | + int64Field: protoInt64.parse(-1), |
| 138 | + uint64Field: protoInt64.uParse(1), |
| 139 | + int32Field: -123, |
| 140 | + fixed64Field: protoInt64.uParse(1), |
| 141 | + fixed32Field: 123, |
| 142 | + boolField: true, |
| 143 | + stringField: "hello world", |
| 144 | + bytesField: new Uint8Array([ |
217 | 145 | 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100,
|
218 | 146 | ]),
|
| 147 | + uint32Field: 123, |
| 148 | + sfixed32Field: -123, |
| 149 | + sfixed64Field: protoInt64.parse(-1), |
| 150 | + sint32Field: -1, |
| 151 | + sint64Field: protoInt64.parse(-1), |
| 152 | + }), |
| 153 | + }, |
| 154 | + { |
| 155 | + name: "repeated scalar values", |
| 156 | + desc: RepeatedScalarValuesMessageSchema, |
| 157 | + msg: create(RepeatedScalarValuesMessageSchema, { |
| 158 | + doubleField: [0.75, 0, 1], |
| 159 | + floatField: [0.75, -0.75], |
| 160 | + int64Field: [protoInt64.parse(-1), protoInt64.parse(-2)], |
| 161 | + uint64Field: [protoInt64.uParse(1), protoInt64.uParse(2)], |
| 162 | + int32Field: [-123, 500], |
| 163 | + fixed64Field: [protoInt64.uParse(1), protoInt64.uParse(99)], |
| 164 | + fixed32Field: [123, 999], |
| 165 | + boolField: [true, false, true], |
| 166 | + stringField: ["hello", "world"], |
| 167 | + bytesField: [ |
| 168 | + new Uint8Array([ |
| 169 | + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, |
| 170 | + ]), |
| 171 | + ], |
| 172 | + uint32Field: [123, 123], |
| 173 | + sfixed32Field: [-123, -123, -123], |
| 174 | + sfixed64Field: [ |
| 175 | + protoInt64.parse(-1), |
| 176 | + protoInt64.parse(-2), |
| 177 | + protoInt64.parse(100), |
| 178 | + ], |
| 179 | + sint32Field: [-1, -2, 999], |
| 180 | + sint64Field: [ |
| 181 | + protoInt64.parse(-1), |
| 182 | + protoInt64.parse(-99), |
| 183 | + protoInt64.parse(99), |
| 184 | + ], |
| 185 | + }), |
| 186 | + }, |
| 187 | + { |
| 188 | + name: "map with scalar keys and values", |
| 189 | + desc: MapsMessageSchema, |
| 190 | + msg: create(MapsMessageSchema, { |
| 191 | + strStrField: { a: "str", b: "xx" }, |
| 192 | + strInt32Field: { a: 123, b: 455 }, |
| 193 | + strInt64Field: { a: protoInt64.parse(123) }, |
| 194 | + strBoolField: { a: true, b: false }, |
| 195 | + strBytesField: { |
| 196 | + a: new Uint8Array([ |
| 197 | + 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, |
| 198 | + ]), |
| 199 | + }, |
| 200 | + int32StrField: { 123: "hello" }, |
| 201 | + int64StrField: { "9223372036854775807": "hello" }, |
| 202 | + boolStrField: { true: "yes", false: "no" }, |
| 203 | + strEnuField: { a: 0, b: 1, c: 2 }, |
| 204 | + int32EnuField: { 1: 0, 2: 1, 0: 2 }, |
| 205 | + int64EnuField: { "-1": 0, "2": 1, "0": 2 }, |
| 206 | + }), |
| 207 | + }, |
| 208 | + { |
| 209 | + name: "repeated field with 1000 messages", |
| 210 | + desc: MessageFieldMessageSchema, |
| 211 | + msg: (() => { |
| 212 | + const message = create(MessageFieldMessageSchema); |
| 213 | + for (let i = 0; i < 1000; i++) { |
| 214 | + message.repeatedMessageField.push( |
| 215 | + create(MessageFieldMessage_TestMessageSchema), |
| 216 | + ); |
| 217 | + } |
| 218 | + return message; |
| 219 | + })(), |
| 220 | + }, |
| 221 | + { |
| 222 | + name: "map field with 1000 messages", |
| 223 | + desc: MapsMessageSchema, |
| 224 | + msg: (() => { |
| 225 | + const message = create(MapsMessageSchema); |
| 226 | + for (let i = 0; i < 1000; i++) { |
| 227 | + message.strMsgField[i.toString()] = create(MapsMessageSchema); |
| 228 | + } |
| 229 | + return message; |
| 230 | + })(), |
| 231 | + }, |
| 232 | + ].flatMap(({ name, msg, desc }) => { |
| 233 | + const bytes = toBinary(desc, msg); |
| 234 | + const jsonString = toJsonString(desc, msg); |
| 235 | + return [ |
| 236 | + { |
| 237 | + name: `fromBinary ${name}`, |
| 238 | + fn: () => { |
| 239 | + fromBinary(desc, bytes); |
| 240 | + }, |
219 | 241 | },
|
220 |
| - int32StrField: { 123: "hello" }, |
221 |
| - int64StrField: { "9223372036854775807": "hello" }, |
222 |
| - boolStrField: { true: "yes", false: "no" }, |
223 |
| - strEnuField: { a: 0, b: 1, c: 2 }, |
224 |
| - int32EnuField: { 1: 0, 2: 1, 0: 2 }, |
225 |
| - int64EnuField: { "-1": 0, "2": 1, "0": 2 }, |
226 |
| - }); |
227 |
| - const data = toBinary(desc, message); |
228 |
| - tests.push({ |
229 |
| - name: `fromBinary map with scalar keys and values (${data.byteLength} bytes)`, |
230 |
| - fn: () => { |
231 |
| - fromBinary(desc, data); |
| 242 | + { |
| 243 | + name: `fromJson ${name}`, |
| 244 | + fn: () => { |
| 245 | + fromJsonString(desc, jsonString); |
| 246 | + }, |
232 | 247 | },
|
233 |
| - }); |
234 |
| - } |
235 |
| - { |
236 |
| - const desc = MessageFieldMessageSchema; |
237 |
| - const message = create(desc); |
238 |
| - for (let i = 0; i < 1000; i++) { |
239 |
| - message.repeatedMessageField.push( |
240 |
| - create(MessageFieldMessage_TestMessageSchema), |
241 |
| - ); |
242 |
| - } |
243 |
| - const data = toBinary(desc, message); |
244 |
| - tests.push({ |
245 |
| - name: `fromBinary repeated field with 1000 messages (${data.byteLength} bytes)`, |
246 |
| - fn: () => { |
247 |
| - fromBinary(desc, data); |
| 248 | + { |
| 249 | + name: `toBinary ${name}`, |
| 250 | + fn: () => { |
| 251 | + toBinary(desc, msg); |
| 252 | + }, |
248 | 253 | },
|
249 |
| - }); |
250 |
| - } |
251 |
| - { |
252 |
| - const desc = MapsMessageSchema; |
253 |
| - const message = create(desc); |
254 |
| - for (let i = 0; i < 1000; i++) { |
255 |
| - message.strMsgField[i.toString()] = create(desc); |
256 |
| - } |
257 |
| - const data = toBinary(desc, message); |
258 |
| - tests.push({ |
259 |
| - name: `fromBinary map field with 1000 messages (${data.byteLength} bytes)`, |
260 |
| - fn: () => { |
261 |
| - fromBinary(desc, data); |
| 254 | + { |
| 255 | + name: `toJson ${name}`, |
| 256 | + fn: () => { |
| 257 | + toJsonString(desc, msg); |
| 258 | + }, |
262 | 259 | },
|
263 |
| - }); |
264 |
| - } |
| 260 | + ]; |
| 261 | + }); |
265 | 262 | return tests;
|
266 | 263 | }
|
267 | 264 |
|
|
0 commit comments