Skip to content

Commit 311afea

Browse files
committed
Add a benchmark for stack trace depth
1 parent ee0f818 commit 311afea

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

Rakefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ namespace :bench do
116116
prepare_benchmark
117117
GraphQLBenchmark.profile_batch_loaders
118118
end
119+
120+
desc "Check the memory footprint of a large schema"
121+
task :profile_schema_memory_footprint do
122+
prepare_benchmark
123+
GraphQLBenchmark.profile_schema_memory_footprint
124+
end
125+
126+
desc "Check the depth of the stacktrace during execution"
127+
task :profile_stack_depth do
128+
prepare_benchmark
129+
GraphQLBenchmark.profile_stack_depth
130+
end
119131
end
120132

121133
namespace :test do

benchmark/run.rb

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,116 @@ def self.profile_batch_loaders
221221

222222
report.pretty_print
223223
end
224+
225+
def self.profile_schema_memory_footprint
226+
schema = nil
227+
report = MemoryProfiler.report do
228+
query_type = Class.new(GraphQL::Schema::Object) do
229+
graphql_name "Query"
230+
100.times do |i|
231+
type = Class.new(GraphQL::Schema::Object) do
232+
graphql_name "Object#{i}"
233+
field :f, Integer
234+
end
235+
field "f#{i}", type
236+
end
237+
end
238+
239+
thing_type = Class.new(GraphQL::Schema::Object) do
240+
graphql_name "Thing"
241+
field :name, String
242+
end
243+
244+
mutation_type = Class.new(GraphQL::Schema::Object) do
245+
graphql_name "Mutation"
246+
100.times do |i|
247+
mutation_class = Class.new(GraphQL::Schema::RelayClassicMutation) do
248+
graphql_name "Do#{i}"
249+
argument :id, "ID"
250+
field :thing, thing_type
251+
field :things, thing_type.connection_type
252+
end
253+
field "f#{i}", mutation: mutation_class
254+
end
255+
end
256+
257+
schema = Class.new(GraphQL::Schema) do
258+
query(query_type)
259+
mutation(mutation_type)
260+
end
261+
end
262+
263+
report.pretty_print
264+
end
265+
266+
class StackDepthSchema < GraphQL::Schema
267+
class Thing < GraphQL::Schema::Object
268+
field :thing, self do
269+
argument :lazy, Boolean, default_value: false
270+
end
271+
272+
def thing(lazy:)
273+
if lazy
274+
-> { :something }
275+
else
276+
:something
277+
end
278+
end
279+
280+
field :stack_trace_depth, Integer do
281+
argument :lazy, Boolean, default_value: false
282+
end
283+
284+
def stack_trace_depth(lazy:)
285+
if lazy
286+
-> { caller.size }
287+
else
288+
caller.size
289+
end
290+
end
291+
end
292+
293+
class Query < GraphQL::Schema::Object
294+
field :thing, Thing
295+
296+
def thing
297+
:something
298+
end
299+
end
300+
301+
query(Query)
302+
lazy_resolve(Proc, :call)
303+
end
304+
305+
def self.profile_stack_depth
306+
query_str = <<-GRAPHQL
307+
query($lazyThing: Boolean!, $lazyStackTrace: Boolean!) {
308+
thing {
309+
thing(lazy: $lazyThing) {
310+
thing(lazy: $lazyThing) {
311+
thing(lazy: $lazyThing) {
312+
thing(lazy: $lazyThing) {
313+
stackTraceDepth(lazy: $lazyStackTrace)
314+
}
315+
}
316+
}
317+
}
318+
}
319+
}
320+
GRAPHQL
321+
322+
very_lazy_res = StackDepthSchema.execute(query_str, variables: { lazyThing: true, lazyStackTrace: true })
323+
pp very_lazy_res
324+
lazy_res = StackDepthSchema.execute(query_str, variables: { lazyThing: true, lazyStackTrace: false })
325+
eager_res = StackDepthSchema.execute(query_str, variables: { lazyThing: false, lazyStackTrace: false })
326+
get_depth = ->(result) { result["data"]["thing"]["thing"]["thing"]["thing"]["thing"]["stackTraceDepth"] }
327+
328+
puts <<~RESULT
329+
Result Depth
330+
---------------------
331+
Eager #{get_depth.call(eager_res)}
332+
Lazy #{get_depth.call(lazy_res)}
333+
Very Lazy #{get_depth.call(very_lazy_res)}
334+
RESULT
335+
end
224336
end

0 commit comments

Comments
 (0)