-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathbench-structfields.jl
116 lines (103 loc) · 2.81 KB
/
bench-structfields.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
module BenchStructureFields
using BenchmarkTools
using Statistics
using Gadfly
using MLStyle
using DataFrames
using MacroTools: @capture
using ..ArbitrarySampler
using ..Utils
lineno = @spec LineNumberNode(::Int isa (x -> mod(x, 100) + 1))
field = @spec :($(::Symbol)::$(::Symbol)) || ::Symbol
specs = [
Symbol("N(fields)=2") => @spec(quote
$$lineno
struct $(::Symbol)
$([$lineno{0, 2}..., $field{2}...]...)
end
end),
Symbol("N(fields)=5") => @spec(quote
$$lineno
struct $(::Symbol)
$([$lineno{0,2}..., $field{5}...]...)
end
end),
Symbol("N(fields)=10") => @spec(quote
$$lineno
struct $(::Symbol)
$([$lineno{0,2}..., $field{10}...]...)
end
end),
Symbol("N(fields)=50") => @spec(quote
$$lineno
struct $(::Symbol)
$([$lineno{0,2}..., $field{50}...]...)
end
end),
]
struct StructField end
@active StructField(x) begin
@match x begin
:($a::$b) => Some((a, b))
a::Symbol => Some((a, Any))
_ => nothing
end
end
using MLStyle.AbstractPatterns: effect
struct PushTo end
function MLStyle.pattern_uncall(::Type{PushTo}, self, _, _, args)
length(args) === 1 || error("PushTo accepts 1 arg.")
container = args[1]
effect() do target, _, _
:(push!($container, $target))
end
end
implementations = [
:MLStyle => function (ex)
fields = Tuple[]
@match ex begin
quote
$(::LineNumberNode)
struct $typename
$(Many[::LineNumberNode||StructField(PushTo(fields))]...)
end
end => (typename, fields)
end
end,
:MacroTools => function (ex)
@capture(ex, struct T_
fields__::Any
end)
(T, fields)
end,
]
records = NamedTuple{(:time_mean, :implementation, :case)}[]
for (spec_id, spec) in specs
# group_key = string(spec_id)
# suite[group_key] = BenchmarkGroup()
for (impl_id, impl_fn) in implementations
bench′ =
@benchmark $impl_fn(sample) setup = (sample = $generate($spec)) samples = 2000
time′ = mean(bench′.times)
@info :bench (spec_id, impl_id, time′)
push!(records, (time_mean = time′, implementation = impl_id, case = spec_id))
end
end
df = DataFrame(records)
@info df
theme = Theme(
guide_title_position = :left,
colorkey_swatch_shape = :circle,
minor_label_font = "Consolas",
major_label_font = "Consolas",
point_size = 5px,
)
report_meantime, df_time = report(
df, Guide.title("Extracting Expr(:struct, ...)");
benchfield = :time_mean
)
open("stats/bench-structfields.txt", "w") do f
write(f, string(df))
end
draw(SVG("stats/bench-structfields.svg", 14inch, 6inch), report_meantime)
end