From 838d48e032ef75d7af540623913cee4c2fb43d3e Mon Sep 17 00:00:00 2001 From: Greg Peairs Date: Mon, 20 Oct 2025 22:37:03 +0000 Subject: [PATCH] Add various benchmarks --- benchmark/autofill.jl | 31 ++++++++++++++++ benchmark/benchmarks.jl | 14 +++++-- benchmark/bounds.jl | 53 +++++++++++++++++++++++++++ benchmark/clipping.jl | 15 ++++++++ benchmark/curves.jl | 47 ++++++++++++++++++++++++ benchmark/intersect.jl | 12 ++++++ benchmark/polygons.jl | 81 +++++++++++++++++++++++++++++++++++++++++ benchmark/schematic.jl | 14 +++++++ benchmark/tune.json | 2 +- 9 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 benchmark/autofill.jl create mode 100644 benchmark/bounds.jl create mode 100644 benchmark/curves.jl create mode 100644 benchmark/intersect.jl create mode 100644 benchmark/polygons.jl create mode 100644 benchmark/schematic.jl diff --git a/benchmark/autofill.jl b/benchmark/autofill.jl new file mode 100644 index 00000000..4529cf6f --- /dev/null +++ b/benchmark/autofill.jl @@ -0,0 +1,31 @@ +# Autofill around paths, first with coarse grid, then with fine grid +function coarse_and_fine_autofill() + cs = CoordinateSystem("autofill_bench", nm) + pa = Path(nm) + pa.metadata = SemanticMeta(:metal_negative) + bspline!(pa, [Point(1000μm, 1000μm)], 90°, Paths.SimpleCPW(10μm, 6μm)) + meander!(pa, 6000μm, 500μm, 200μm, -180°) + bspline!(pa, [Point(4000μm, 0μm)], 0°) + # Place two copies of paths, one rotated + addref!(cs, pa) + addref!(cs, pa, Point(-500μm, 0μm), rot=90°) + + # Autofill grids + coarse_grid_x = (-3000:250:5000)μm + coarse_grid_y = (-1000:250:5000)μm + fine_grid_x = (-3000:25:5000)μm + fine_grid_y = (-1000:25:5000)μm + + # Coordinate systems holding "dummy" geometry (the thing filling space) + coarse_dummy = CoordinateSystem("coarse", nm) + place!(coarse_dummy, centered(Rounded(Rectangle(100μm, 100μm), 50μm)), :metal_negative) + fine_dummy = CoordinateSystem("fine", nm) + place!(fine_dummy, centered(Rounded(Rectangle(10μm, 10μm), 5μm)), :metal_negative) + + # Autofill + autofill!(cs, coarse_dummy, coarse_grid_x, coarse_grid_y, make_halo(150μm)) + autofill!(cs, fine_dummy, fine_grid_x, fine_grid_y, make_halo(50μm)) + return +end + +SUITE["autofill"] = @benchmarkable coarse_and_fine_autofill() diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl index db93acd0..6a32905e 100644 --- a/benchmark/benchmarks.jl +++ b/benchmark/benchmarks.jl @@ -1,7 +1,15 @@ using Test, BenchmarkTools -const SUITE = BenchmarkGroup() - using DeviceLayout, Pkg, FileIO, Unitful, DeviceLayout.PreferredUnits +using DeviceLayout.SchematicDrivenLayout +import Random: default_rng, rand, seed! + const um = μm +const SUITE = BenchmarkGroup() -include(joinpath(@__DIR__, "clipping.jl")) +include("autofill.jl") +include("bounds.jl") +include("clipping.jl") +include("curves.jl") +include("intersect.jl") +include("polygons.jl") +include("schematic.jl") diff --git a/benchmark/bounds.jl b/benchmark/bounds.jl new file mode 100644 index 00000000..87ff0c2e --- /dev/null +++ b/benchmark/bounds.jl @@ -0,0 +1,53 @@ +SUITE["bounds"] = BenchmarkGroup() +SUITE["flatten"] = BenchmarkGroup() + +rng = seed!(default_rng(), 111) +# Generate rectangles from random points +num_rects = 1_000 +p1s = reinterpret(Point{Int}, rand(Int, 2, num_rects)) +p2s = reinterpret(Point{Int}, rand(Int, 2, num_rects)) +random_rectangles = [Rectangle(p1, p2) for (p1, p2) in zip(p1s, p2s)] +# Circles around points +random_circles = [circle_polygon(1.0, 10°) for p1 in p1s] + +# Cell with same circle coordinate system referenced many times at top level +c_shallow = Cell{Float64}("shallow") +c_circ = Cell{Float64}("circle") +render!(c_circ, circle_polygon(10.0, 10°)) +rots = rand(num_rects) * 2π +for (p1, rot) in zip(p1s, rots) + addref!(c_shallow, c_circ, p1, rot=rot) +end + +# Cell with reference to a circle coordinate systems holding a reference to another +# and so on to `num_rects` depth +c_nested = Cell{Float64}("nested") +rots = rand(num_rects) * 2π +nextcell = c_nested +for (p1, rot) in zip(p1s, rots) + global nextcell + c = Cell{Float64}(uniquename("nested")) + addref!(nextcell, c, p1, rot=rot) + nextcell = c + render!(nextcell, circle_polygon(10.0, 10°)) +end + +# Array reference with around 1000 circles +c_arrayed = Cell{Float64}("arrayed") +addarr!( + c_arrayed, + c_circ, + numrows=31, + numcols=31, + deltarow=Point(0.0, 10.0), + deltacol=Point(10.0, 0.0) +) + +SUITE["bounds"]["random_rectangles"] = @benchmarkable bounds($random_rectangles) +SUITE["bounds"]["random_circles"] = @benchmarkable bounds($random_circles) +SUITE["bounds"]["shallow_references"] = @benchmarkable bounds($c_shallow) +SUITE["bounds"]["nested_references"] = @benchmarkable bounds($c_nested) + +SUITE["flatten"]["shallow_references"] = @benchmarkable flatten($c_shallow) +SUITE["flatten"]["nested_references"] = @benchmarkable flatten($c_nested) +SUITE["flatten"]["array_reference"] = @benchmarkable flatten($c_arrayed) diff --git a/benchmark/clipping.jl b/benchmark/clipping.jl index b4a99e33..5b8e7525 100644 --- a/benchmark/clipping.jl +++ b/benchmark/clipping.jl @@ -1,6 +1,7 @@ SUITE["clipping"] = BenchmarkGroup() SUITE["clipping"]["difference2d"] = BenchmarkGroup() +# Differences using various pregenerated square arrays for name in [ :difference2d_100_square, :difference2d_961_square, @@ -27,3 +28,17 @@ c = element_metadata(difference2d_8000_skew) a = splice!(b, findall(m -> m == GDSMeta(0, 0), c)) SUITE["clipping"]["difference2d"]["8000_skew"] = @benchmarkable difference2d($(a), $(b)) + +# Offset a hexagon then take the difference across some overlapping copies +function offset_difference() + c = Cell{Float64}("test") + poly = circle_polygon(1.5, 60°) + render!(c, poly) + ref = aref(c, Point(-3.0, 5.0), nc=4, deltacol=Point(2.0, 0.0)) + els = [poly; elements(flatten(ref))] + off = offset(els, 0.2) + boo = difference2d(off, els) + return render!(c, boo, GDSMeta(1)) # Render to force interiorcuts +end + +SUITE["clipping"]["difference2d_offset"] = @benchmarkable offset_difference() diff --git a/benchmark/curves.jl b/benchmark/curves.jl new file mode 100644 index 00000000..e87a5820 --- /dev/null +++ b/benchmark/curves.jl @@ -0,0 +1,47 @@ +SUITE["curves"] = BenchmarkGroup() + +# Build and render turns +function turns() + c = Cell{Float64}("test") + turn_path = Path{Float64}() + for i = 1:10 + turn!(turn_path, 45°, 20.0 * i, Paths.CPW(10.0, 6.0)) + turn!(turn_path, -45°, 20.0 * i) + end + return render!(c, turn_path, GDSMeta()) +end + +# Build and render B-splines +function bsplines() + c = Cell{Float64}("test") + bspline_path = Path{Float64}() + for i = 1:10 + bspline!( + bspline_path, + [p0(bspline_path) + Point(20 * i, 10 * i)], + 0°, + Paths.CPW(10.0, 6.0), + endpoints_speed=20.0 * i + ) + end + return render!(c, bspline_path, GDSMeta()) +end + +# Approximate offset curves with B-splines +function offset_bspline_approx() + bspline_path = Path{Float64}() + for i = 1:10 + bspline!( + bspline_path, + [p0(bspline_path) + Point(20 * i, 10 * i^2)], + 0°, + Paths.CPW(10.0, 6.0), + endpoints_speed=20.0 * i + ) + Paths.bspline_approximation(Paths.offset(bspline_path[end].seg, 11.0)) + end +end + +SUITE["curves"]["turns_render"] = @benchmarkable turns() +SUITE["curves"]["bsplines_render"] = @benchmarkable bsplines() +SUITE["curves"]["offset_bspline_approximation"] = @benchmarkable offset_bspline_approx() diff --git a/benchmark/intersect.jl b/benchmark/intersect.jl new file mode 100644 index 00000000..2d55b1c7 --- /dev/null +++ b/benchmark/intersect.jl @@ -0,0 +1,12 @@ +# Crossing vertical and horizontal paths +paths_vert = [Path(i * 0.1mm, (-1)^(i + 1) * (1mm), α0=(-1)^i * π / 2) for i = -5:5] +paths_horiz = [Path((-1)^(i) * (1mm), i * 0.1mm, α0=(-1)^i * π / 2 + π / 2) for i = -5:5] + +sty = Paths.SimpleCPW(10μm, 6μm) +straight!.(paths_vert, 2mm, Ref(sty)) +straight!.(paths_horiz, 2mm, Ref(sty)) +all_paths = vcat(paths_vert, paths_horiz) + +SUITE["intersection"] = BenchmarkGroup() +SUITE["intersection"]["straight_lines"] = + @benchmarkable Intersect.prepared_intersections($all_paths) diff --git a/benchmark/polygons.jl b/benchmark/polygons.jl new file mode 100644 index 00000000..99bb9318 --- /dev/null +++ b/benchmark/polygons.jl @@ -0,0 +1,81 @@ +SUITE["polygons"] = BenchmarkGroup() +SUITE["polygons"]["circles"] = BenchmarkGroup() +SUITE["polygons"]["rectangles"] = BenchmarkGroup() + +# Render and optionally export n rectangles +function rectangles(n; output_dir=nothing) + c = Cell{Float64}("rectangles") + for i = 1:n + render!(c, Rectangle(Point(i, 0.0), Point(i + 1, 1.0))) + end + return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_rectangles.gds"), c) +end + +# As above but with units +function rectangles_units(n, unit; output_dir=nothing) + um = uconvert(unit, DeviceLayout.onemicron(1unit)) + c = Cell{typeof(1.0nm)}("rectangles") # coordinatetype(c) may or may not be same as unit + for i = 1:n + render!(c, Rectangle(Point(i * um, 0 * um), Point((i + 1) * um, 1 * um))) + end + return !isnothing(output_dir) && + save(joinpath(output_dir, "$(n)_rectangles_units.gds"), c) +end + +# Render circles using `circle_polygon` to calculate polygon points directly +# (use ~maxiumum number of points for single GDSII polygon -- other extreme from rectangles) +function circles_direct(n; output_dir=nothing) + c = Cell{Float64}("circles") + for i = 1:n + render!(c, Point(i, 0.0) + circle_polygon(1, 2π / 8000)) + end + return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles.gds"), c) +end + +# As above but with units +function circles_direct_units(n, unit; output_dir=nothing) + um = uconvert(unit, DeviceLayout.onemicron(1unit)) + c = Cell{typeof(1.0nm)}("circles") # coordinatetype(c) may or may not be same as unit + for i = 1:n + render!(c, Point(i * um, 0.0 * um) + circle_polygon(1 * um, 2π / 8000)) + end + return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles_units.gds"), c) +end + +# Render circles using `Circle` entity and `Δθ` keyword option for discretization +function circles_entity_delta(n; output_dir=nothing) + c = Cell{Float64}("circles") + for i = 1:n + render!(c, Circle(Point(i, 0.0), 1.0), Δθ=2π / 8000) + end + return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles_delta.gds"), c) +end + +# As above but using `atol` for discretization with the same number of points +function circles_entity_atol(n; output_dir=nothing) + c = Cell{Float64}("circles") + for i = 1:n + render!(c, Circle(Point(i, 0.0), 1.0), atol=4e-7)#, atol=7.714e-8) # 7999 points + end + return !isnothing(output_dir) && save(joinpath(output_dir, "$(n)_circles_atol.gds"), c) +end + +dir = mktempdir() +SUITE["polygons"]["rectangles"]["render"] = @benchmarkable rectangles(10_000) +SUITE["polygons"]["rectangles"]["render_gds"] = + @benchmarkable rectangles(10_000, output_dir=$dir) +SUITE["polygons"]["rectangles"]["render_units"] = + @benchmarkable rectangles_units(10_000, $nm) +SUITE["polygons"]["rectangles"]["render_units_gds"] = + @benchmarkable rectangles_units(10_000, $nm, output_dir=$dir) +SUITE["polygons"]["rectangles"]["render_convertunits"] = + @benchmarkable rectangles_units(10_000, $μm) +SUITE["polygons"]["circles"]["direct"] = @benchmarkable circles_direct(1_000) +SUITE["polygons"]["circles"]["direct_gds"] = + @benchmarkable circles_direct(1_000, output_dir=$dir) +SUITE["polygons"]["circles"]["direct_units"] = + @benchmarkable circles_direct_units(1_000, $nm) +SUITE["polygons"]["circles"]["direct_units_gds"] = + @benchmarkable circles_direct_units(1_000, $nm, output_dir=$dir) +SUITE["polygons"]["circles"]["entity_delta"] = @benchmarkable circles_entity_delta(1_000) +SUITE["polygons"]["circles"]["entity_atol"] = @benchmarkable circles_entity_atol(1_000) diff --git a/benchmark/schematic.jl b/benchmark/schematic.jl new file mode 100644 index 00000000..5f859f98 --- /dev/null +++ b/benchmark/schematic.jl @@ -0,0 +1,14 @@ +# Schematic with chain of spacers rotated at 45 degrees +g = SchematicGraph("test") +lastnode = add_node!(g, Spacer{Float64}(p1=Point(10.0, 10.0))) +for i = 1:100 + global lastnode + lastnode = fuse!( + g, + lastnode => :p1_east, + Spacer{Float64}(p1=Point(10.0, 10.0)) => :p0_southwest + ) +end + +SUITE["schematic"] = BenchmarkGroup() +SUITE["schematic"]["plan"] = @benchmarkable plan($g; log_dir=nothing) diff --git a/benchmark/tune.json b/benchmark/tune.json index b21f198b..f0263211 100644 --- a/benchmark/tune.json +++ b/benchmark/tune.json @@ -1 +1 @@ -[{"Julia":"1.6.0-rc2","BenchmarkTools":"0.4.3"},[["BenchmarkGroup",{"data":{"clipping":["BenchmarkGroup",{"data":{"difference2d":["BenchmarkGroup",{"data":{"100_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"3600_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"961_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"19881_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"8000_skew":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"10000_square":["BenchmarkTools.Parameters",{"gctrial":true,"time_tolerance":0.05,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]},"tags":[]}]},"tags":[]}]]] \ No newline at end of file +[{"Julia":"1.12.0","BenchmarkTools":{"major":1,"minor":6,"patch":2,"prerelease":[],"build":[]}},[["BenchmarkGroup",{"data":{"schematic":["BenchmarkGroup",{"data":{"plan":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"curves":["BenchmarkGroup",{"data":{"turns_render":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"bsplines_render":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"offset_bspline_approximation":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"polygons":["BenchmarkGroup",{"data":{"rectangles":["BenchmarkGroup",{"data":{"render_units":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render_units_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render_convertunits":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"render_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"circles":["BenchmarkGroup",{"data":{"direct":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"entity_delta":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"direct_units_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"direct_units":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"entity_atol":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"direct_gds":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]},"tags":[]}],"flatten":["BenchmarkGroup",{"data":{"shallow_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"array_reference":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"nested_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"clipping":["BenchmarkGroup",{"data":{"difference2d_offset":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"difference2d":["BenchmarkGroup",{"data":{"100_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"3600_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"961_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"19881_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"8000_skew":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"10000_square":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]},"tags":[]}],"bounds":["BenchmarkGroup",{"data":{"random_rectangles":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"shallow_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"random_circles":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}],"nested_references":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"intersection":["BenchmarkGroup",{"data":{"straight_lines":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}],"autofill":["Parameters",{"gctrial":true,"time_tolerance":0.05,"evals_set":false,"samples":10000,"evals":1,"gcsample":false,"seconds":5.0,"overhead":0.0,"memory_tolerance":0.01}]},"tags":[]}]]] \ No newline at end of file