Skip to content

Commit 6aeb50b

Browse files
JoviDeCroockbenjie
authored andcommitted
Increase print/visit performance (#4312)
This replaces our expensive method that changes the underlying V8 shape multiple times with a loop that preserves the identity as much as possible. ``` ⏱ Print kitchen sink document 1 tests completed. 2 tests completed. HEAD x 9,290 ops/sec ±0.21% x 1.51 KB/op (24 runs sampled) BASE x 2,645 ops/sec ±0.18% x 2.18 KB/op (11 runs sampled) ``` --------- Co-authored-by: Benjie <code@benjiegillam.com>
1 parent 078da79 commit 6aeb50b

File tree

4 files changed

+84
-4
lines changed

4 files changed

+84
-4
lines changed

benchmark/fixtures.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export const bigSchemaSDL = fs.readFileSync(
55
'utf8',
66
);
77

8+
export const bigDocumentSDL = JSON.parse(
9+
fs.readFileSync(new URL('kitchen-sink.graphql', import.meta.url), 'utf8'),
10+
);
11+
812
export const bigSchemaIntrospectionResult = JSON.parse(
913
fs.readFileSync(new URL('github-schema.json', import.meta.url), 'utf8'),
1014
);

benchmark/kitchen-sink.graphql

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery {
2+
whoever123is: node(id: [123, 456]) {
3+
id
4+
... on User @onInlineFragment {
5+
field2 {
6+
id
7+
alias: field1(first: 10, after: $foo) @include(if: $foo) {
8+
id
9+
...frag @onFragmentSpread
10+
}
11+
}
12+
}
13+
... @skip(unless: $foo) {
14+
id
15+
}
16+
... {
17+
id
18+
}
19+
}
20+
}
21+
22+
mutation likeStory @onMutation {
23+
like(story: 123) @onField {
24+
story {
25+
id @onField
26+
}
27+
}
28+
}
29+
30+
subscription StoryLikeSubscription(
31+
$input: StoryLikeSubscribeInput @onVariableDefinition
32+
) @onSubscription {
33+
storyLikeSubscribe(input: $input) {
34+
story {
35+
likers {
36+
count
37+
}
38+
likeSentence {
39+
text
40+
}
41+
}
42+
}
43+
}
44+
45+
fragment frag on Friend @onFragmentDefinition {
46+
foo(
47+
size: $size
48+
bar: $b
49+
obj: {
50+
key: "value"
51+
block: """
52+
block string uses \"""
53+
"""
54+
}
55+
)
56+
}
57+
58+
{
59+
unnamed(truthy: true, falsy: false, nullish: null)
60+
query
61+
}
62+
63+
query {
64+
__typename
65+
}

benchmark/printer-benchmark.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { parse } from 'graphql/language/parser.js';
2+
import { print } from 'graphql/language/printer.js';
3+
4+
import { bigDocumentSDL } from './fixtures.js';
5+
6+
const document = parse(bigDocumentSDL);
7+
8+
export const benchmark = {
9+
name: 'Print kitchen sink document',
10+
count: 1000,
11+
measure() {
12+
print(document);
13+
},
14+
};

src/language/visitor.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,7 @@ export function visit(
220220
}
221221
}
222222
} else {
223-
node = Object.defineProperties(
224-
{},
225-
Object.getOwnPropertyDescriptors(node),
226-
);
223+
node = { ...node };
227224
for (const [editKey, editValue] of edits) {
228225
node[editKey] = editValue;
229226
}

0 commit comments

Comments
 (0)