Skip to content

Commit 45ec503

Browse files
authored
perf: Reduce generated code overhead (#2212)
1 parent 660a244 commit 45ec503

16 files changed

Lines changed: 2507 additions & 1647 deletions

File tree

bench/data/static_pbjs.js

Lines changed: 120 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ $root.Test = (function() {
2424
Test.encode = function encode(message, writer) {
2525
if (!writer)
2626
writer = $Writer.create();
27-
if (message.string != null && message.string.length)
27+
if (message.string != null && Object.hasOwnProperty.call(message, "string"))
2828
writer.uint32(10).string(message.string);
29-
if (message.uint32 != null && Number(message.uint32) !== 0)
29+
if (message.uint32 != null && Object.hasOwnProperty.call(message, "uint32"))
3030
writer.uint32(16).uint32(message.uint32);
3131
if (message.inner != null && Object.hasOwnProperty.call(message, "inner"))
3232
$root.Test.Inner.encode(message.inner, writer.uint32(26).fork()).ldelim();
33-
if (message.float != null && Number(message.float) !== 0)
33+
if (message.float != null && Object.hasOwnProperty.call(message, "float"))
3434
writer.uint32(37).float(message.float);
3535
if (message.$unknowns != null && Object.hasOwnProperty.call(message, "$unknowns"))
3636
for (var i = 0; i < message.$unknowns.length; ++i)
@@ -45,37 +45,53 @@ $root.Test = (function() {
4545
_depth = 0;
4646
if (_depth > $Reader.recursionLimit)
4747
throw Error("max depth exceeded");
48-
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Test();
48+
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Test(), value;
4949
while (reader.pos < end) {
5050
var start = reader.pos;
5151
var tag = reader.uint32();
5252
if (tag === _end) {
5353
_end = undefined;
5454
break;
5555
}
56-
switch (tag) {
57-
case 10: {
58-
message.string = reader.string();
59-
break;
56+
var wireType = tag & 7;
57+
switch (tag >>>= 3) {
58+
case 1: {
59+
if (wireType !== 2)
60+
break;
61+
if ((value = reader.string()).length)
62+
message.string = value;
63+
else
64+
delete message.string;
65+
continue;
6066
}
61-
case 16: {
62-
message.uint32 = reader.uint32();
63-
break;
67+
case 2: {
68+
if (wireType !== 0)
69+
break;
70+
if (value = reader.uint32())
71+
message.uint32 = value;
72+
else
73+
delete message.uint32;
74+
continue;
6475
}
65-
case 26: {
76+
case 3: {
77+
if (wireType !== 2)
78+
break;
6679
message.inner = $root.Test.Inner.decode(reader, reader.uint32(), undefined, _depth + 1, message.inner);
67-
break;
80+
continue;
6881
}
69-
case 37: {
70-
message.float = reader.float();
71-
break;
82+
case 4: {
83+
if (wireType !== 5)
84+
break;
85+
if ((value = reader.float()) !== 0)
86+
message.float = value;
87+
else
88+
delete message.float;
89+
continue;
7290
}
73-
default:
74-
reader.skipType(tag & 7, _depth, tag >>> 3);
75-
$util.makeProp(message, "$unknowns", false);
76-
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
77-
break;
7891
}
92+
reader.skipType(wireType, _depth, tag);
93+
$util.makeProp(message, "$unknowns", false);
94+
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
7995
}
8096
if (_end !== undefined)
8197
throw Error("missing end group");
@@ -98,7 +114,7 @@ $root.Test = (function() {
98114
Inner.encode = function encode(message, writer) {
99115
if (!writer)
100116
writer = $Writer.create();
101-
if (message.int32 != null && Number(message.int32) !== 0)
117+
if (message.int32 != null && Object.hasOwnProperty.call(message, "int32"))
102118
writer.uint32(8).int32(message.int32);
103119
if (message.innerInner != null && Object.hasOwnProperty.call(message, "innerInner"))
104120
$root.Test.Inner.InnerInner.encode(message.innerInner, writer.uint32(18).fork()).ldelim();
@@ -117,33 +133,41 @@ $root.Test = (function() {
117133
_depth = 0;
118134
if (_depth > $Reader.recursionLimit)
119135
throw Error("max depth exceeded");
120-
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Test.Inner();
136+
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Test.Inner(), value;
121137
while (reader.pos < end) {
122138
var start = reader.pos;
123139
var tag = reader.uint32();
124140
if (tag === _end) {
125141
_end = undefined;
126142
break;
127143
}
128-
switch (tag) {
129-
case 8: {
130-
message.int32 = reader.int32();
131-
break;
144+
var wireType = tag & 7;
145+
switch (tag >>>= 3) {
146+
case 1: {
147+
if (wireType !== 0)
148+
break;
149+
if (value = reader.int32())
150+
message.int32 = value;
151+
else
152+
delete message.int32;
153+
continue;
132154
}
133-
case 18: {
155+
case 2: {
156+
if (wireType !== 2)
157+
break;
134158
message.innerInner = $root.Test.Inner.InnerInner.decode(reader, reader.uint32(), undefined, _depth + 1, message.innerInner);
135-
break;
159+
continue;
136160
}
137-
case 26: {
161+
case 3: {
162+
if (wireType !== 2)
163+
break;
138164
message.outer = $root.Outer.decode(reader, reader.uint32(), undefined, _depth + 1, message.outer);
139-
break;
165+
continue;
140166
}
141-
default:
142-
reader.skipType(tag & 7, _depth, tag >>> 3);
143-
$util.makeProp(message, "$unknowns", false);
144-
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
145-
break;
146167
}
168+
reader.skipType(wireType, _depth, tag);
169+
$util.makeProp(message, "$unknowns", false);
170+
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
147171
}
148172
if (_end !== undefined)
149173
throw Error("missing end group");
@@ -166,11 +190,11 @@ $root.Test = (function() {
166190
InnerInner.encode = function encode(message, writer) {
167191
if (!writer)
168192
writer = $Writer.create();
169-
if (message.long != null && (typeof message.long === "object" ? message.long.low || message.long.high : Number(message.long) !== 0))
193+
if (message.long != null && Object.hasOwnProperty.call(message, "long"))
170194
writer.uint32(8).int64(message.long);
171-
if (message["enum"] != null && Number(message["enum"]) !== 0)
195+
if (message["enum"] != null && Object.hasOwnProperty.call(message, "enum"))
172196
writer.uint32(16).int32(message["enum"]);
173-
if (message.sint32 != null && Number(message.sint32) !== 0)
197+
if (message.sint32 != null && Object.hasOwnProperty.call(message, "sint32"))
174198
writer.uint32(24).sint32(message.sint32);
175199
if (message.$unknowns != null && Object.hasOwnProperty.call(message, "$unknowns"))
176200
for (var i = 0; i < message.$unknowns.length; ++i)
@@ -185,33 +209,47 @@ $root.Test = (function() {
185209
_depth = 0;
186210
if (_depth > $Reader.recursionLimit)
187211
throw Error("max depth exceeded");
188-
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Test.Inner.InnerInner();
212+
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Test.Inner.InnerInner(), value;
189213
while (reader.pos < end) {
190214
var start = reader.pos;
191215
var tag = reader.uint32();
192216
if (tag === _end) {
193217
_end = undefined;
194218
break;
195219
}
196-
switch (tag) {
197-
case 8: {
198-
message.long = reader.int64();
199-
break;
220+
var wireType = tag & 7;
221+
switch (tag >>>= 3) {
222+
case 1: {
223+
if (wireType !== 0)
224+
break;
225+
if (typeof (value = reader.int64()) === "object" ? value.low || value.high : value !== 0)
226+
message.long = value;
227+
else
228+
delete message.long;
229+
continue;
200230
}
201-
case 16: {
202-
message["enum"] = reader.int32();
203-
break;
231+
case 2: {
232+
if (wireType !== 0)
233+
break;
234+
if (value = reader.int32())
235+
message["enum"] = value;
236+
else
237+
delete message["enum"];
238+
continue;
204239
}
205-
case 24: {
206-
message.sint32 = reader.sint32();
207-
break;
240+
case 3: {
241+
if (wireType !== 0)
242+
break;
243+
if (value = reader.sint32())
244+
message.sint32 = value;
245+
else
246+
delete message.sint32;
247+
continue;
208248
}
209-
default:
210-
reader.skipType(tag & 7, _depth, tag >>> 3);
211-
$util.makeProp(message, "$unknowns", false);
212-
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
213-
break;
214249
}
250+
reader.skipType(wireType, _depth, tag);
251+
$util.makeProp(message, "$unknowns", false);
252+
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
215253
}
216254
if (_end !== undefined)
217255
throw Error("missing end group");
@@ -259,7 +297,7 @@ $root.Outer = (function() {
259297
writer.bool(message.bool[i]);
260298
writer.ldelim();
261299
}
262-
if (message.double != null && Number(message.double) !== 0)
300+
if (message.double != null && Object.hasOwnProperty.call(message, "double"))
263301
writer.uint32(17).double(message.double);
264302
if (message.$unknowns != null && Object.hasOwnProperty.call(message, "$unknowns"))
265303
for (var i = 0; i < message.$unknowns.length; ++i)
@@ -274,37 +312,45 @@ $root.Outer = (function() {
274312
_depth = 0;
275313
if (_depth > $Reader.recursionLimit)
276314
throw Error("max depth exceeded");
277-
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Outer();
315+
var end = length === undefined ? reader.len : reader.pos + length, message = _target || new $root.Outer(), value;
278316
while (reader.pos < end) {
279317
var start = reader.pos;
280318
var tag = reader.uint32();
281319
if (tag === _end) {
282320
_end = undefined;
283321
break;
284322
}
285-
switch (tag) {
286-
case 8:
287-
case 10: {
288-
if (!(message.bool && message.bool.length))
289-
message.bool = [];
290-
if ((tag & 7) === 2) {
323+
var wireType = tag & 7;
324+
switch (tag >>>= 3) {
325+
case 1: {
326+
if (wireType === 2) {
327+
if (!(message.bool && message.bool.length))
328+
message.bool = [];
291329
var end2 = reader.uint32() + reader.pos;
292330
while (reader.pos < end2)
293331
message.bool.push(reader.bool());
294-
} else
295-
message.bool.push(reader.bool());
296-
break;
332+
continue;
333+
}
334+
if (wireType !== 0)
335+
break;
336+
if (!(message.bool && message.bool.length))
337+
message.bool = [];
338+
message.bool.push(reader.bool());
339+
continue;
297340
}
298-
case 17: {
299-
message.double = reader.double();
300-
break;
341+
case 2: {
342+
if (wireType !== 1)
343+
break;
344+
if ((value = reader.double()) !== 0)
345+
message.double = value;
346+
else
347+
delete message.double;
348+
continue;
301349
}
302-
default:
303-
reader.skipType(tag & 7, _depth, tag >>> 3);
304-
$util.makeProp(message, "$unknowns", false);
305-
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
306-
break;
307350
}
351+
reader.skipType(wireType, _depth, tag);
352+
$util.makeProp(message, "$unknowns", false);
353+
(message.$unknowns || (message.$unknowns = [])).push(reader.raw(start, reader.pos));
308354
}
309355
if (_end !== undefined)
310356
throw Error("missing end group");

cli/targets/static.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,13 @@ var shortVars = {
166166
"w": "writer",
167167
"m": "message",
168168
"t": "tag",
169+
"t2": "tag2",
170+
"u": "wireType",
169171
"l": "length",
170172
"s": "start",
171173
"c": "end", "c2": "end2",
172174
"k": "key",
175+
"v": "value",
173176
"ks": "keys", "ks2": "keys2",
174177
"e": "error",
175178
"f": "impl",

src/converter.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ converter.fromObject = function fromObject(mtype) {
118118
("var m=new this.ctor");
119119
for (var i = 0; i < fields.length; ++i) {
120120
var field = fields[i].resolve(),
121-
prop = util.safeProp(field.name);
121+
prop = util.safeProp(field.name),
122+
implicitPresence = !field.hasPresence && !field.repeated && !field.map
123+
&& (field.resolvedType instanceof Enum || types.basic[field.type] !== undefined);
122124

123125
// Map fields
124126
if (field.map) { gen
@@ -149,7 +151,23 @@ converter.fromObject = function fromObject(mtype) {
149151
} else {
150152
if (!(field.resolvedType instanceof Enum)) gen // no need to test for null/undefined if an enum (uses switch)
151153
("if(d%s!=null){", prop); // !== undefined && !== null
154+
if (implicitPresence) {
155+
if (field.resolvedType instanceof Enum) gen
156+
("if(d%s!==%j&&(typeof d%s!==\"string\"||types[%i].values[d%s]!==%j)){", prop, field.typeDefault, prop, i, prop, field.typeDefault);
157+
else if (field.type === "string") gen
158+
("if(typeof d%s!==\"string\"||d%s.length){", prop, prop);
159+
else if (field.type === "bytes") gen
160+
("if(d%s.length){", prop);
161+
else if (field.type === "bool") gen
162+
("if(d%s){", prop);
163+
else if (types.long[field.type] !== undefined) gen
164+
("if(typeof d%s===\"object\"?d%s.low||d%s.high:Number(d%s)!==0){", prop, prop, prop, prop);
165+
else gen
166+
("if(Number(d%s)!==0){", prop);
167+
}
152168
genValuePartial_fromObject(gen, field, /* not sorted */ i, prop);
169+
if (implicitPresence) gen
170+
("}");
153171
if (!(field.resolvedType instanceof Enum)) gen
154172
("}");
155173
}

0 commit comments

Comments
 (0)