Skip to content

Commit e6d969c

Browse files
authored
Update README.md
1 parent 49e0c4e commit e6d969c

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@ _**The original prototype of the core algorithm for Shopify's _GraphQL Cardinal_
66

77
GraphQL requests have two dimensions: _depth_ and _breadth_. The depth dimension is finite as defined by the request document, while the breadth dimension scales by the width of the response data (and can grow extremely large).
88

9-
![Execution flows](./images/exec-flows.png)
9+
![Execution flows](./images/exec-flow.png)
1010

11-
Traditional GraphQL implementations execute _depth-first_, which resolves every field of every object in the response individually, making resolver overhead (resolver calls, tracing, intermediary promises) scale by **depth × breadth**. To execute _breadth-first_, we instead resolve each selection position spanning depth only once with an aggregated breadth of objects. Now resolver overhead only scales by the static depth of the document, and processing list repetitions becomes considerably faster.
11+
Traditional GraphQL implementations execute _depth-first_, which resolves every field of every object in the response individually, making resolver overhead (resolver calls, tracing, intermediary promises) scale by **depth × breadth**. To execute _breadth-first_, we instead resolve each selection depth only once with an aggregated breadth of objects, so resolver overhead now scales by **depth-only**. This makes processing list repetitions considerably faster.
1212

1313
```shell
14-
graphql-ruby: 140002 resolvers
14+
graphql-ruby (depth): 140002 resolvers
1515
1.087 (± 0.0%) i/s (919.76 ms/i) - 6.000 in 5.526807s
1616
graphql-breadth_exec 140002 resolvers
1717
21.314 (± 9.4%) i/s (46.92 ms/i) - 108.000 in 5.095015s
1818

1919
Comparison:
2020
graphql-breadth_exec 140002 resolvers: 21.3 i/s
21-
graphql-ruby: 140002 resolvers: 1.1 i/s - 19.60x slower
21+
graphql-ruby (depth): 140002 resolvers: 1.1 i/s - 19.60x slower
2222
```
2323

24-
## Breadth means native batching
24+
## Batching advantages
2525

2626
Breadth-first resolvers look a little different than we're used to: they recieve `objects` and return a mapped set.
2727

@@ -31,7 +31,7 @@ def resolve(objects, args, cxt)
3131
end
3232
```
3333

34-
In effect, all field instances are automatically batched without the use of DataLoader. However, we frequently need to batch work across field instances (ex: same field using different aliases, different fields sharing a query, etc.), which still involves DataLoader promises. Breadth is still remarkably efficient at this because it can bind many object loads to a single promise, versus resolving a promise per loaded object
34+
This means all field instances are inherently batched as a function of the engine without using DataLoader promise patterns. However, promises are still relevant for batching work _across field instances_ (ie: same field using different aliases, or different fields sharing a query, etc.), and they can be considerably more efficient in breadth execution by binding many objects to a single promise rather than generating a promise per object:
3535

3636
![Promises](./images/promises.png)
3737

0 commit comments

Comments
 (0)