Skip to content

Commit 03f2de5

Browse files
committed
Serialize LinuxPerf.Stats in BenchmarkTools instead of relying on convert
1 parent 529d153 commit 03f2de5

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

src/serialization.jl

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,32 @@ const VERSIONS = Dict(
55
)
66

77
# TODO: Add any new types as they're added
8-
const SUPPORTED_TYPES = Dict{Symbol,Type}(
9-
Base.typename(x).name => x for x in [
10-
BenchmarkGroup,
11-
Parameters,
12-
TagFilter,
13-
Trial,
14-
TrialEstimate,
15-
TrialJudgement,
16-
TrialRatio,
17-
]
8+
const SUPPORTED_TYPES = Set{Type}((
9+
BenchmarkGroup,
10+
Parameters,
11+
TagFilter,
12+
Trial,
13+
TrialEstimate,
14+
TrialJudgement,
15+
TrialRatio,
16+
LinuxPerf.Stats,
17+
LinuxPerf.ThreadStats,
18+
LinuxPerf.Counter,
19+
LinuxPerf.EventType
20+
))
21+
const LOWERED_TO_SUPPORTED_TYPES = Dict{Symbol,Type}(
22+
Base.typename(x).name => x for x in SUPPORTED_TYPES
1823
)
1924
# n.b. Benchmark type not included here, since it is gensym'd
2025

21-
function JSON.lower(x::Union{values(SUPPORTED_TYPES)...})
26+
function JSON.lower(x::Union{SUPPORTED_TYPES...})
2227
d = Dict{String,Any}()
2328
T = typeof(x)
2429
for i in 1:nfields(x)
2530
name = String(fieldname(T, i))
2631
field = getfield(x, i)
2732
ft = typeof(field)
28-
value = ft <: get(SUPPORTED_TYPES, nameof(ft), Union{}) ? JSON.lower(field) : field
33+
value = (ft in SUPPORTED_TYPES) ? JSON.lower(field) : field
2934
d[name] = value
3035
end
3136
return [string(nameof(typeof(x))), d]
@@ -40,26 +45,25 @@ function safeeval(x::Expr)
4045
x.head === :tuple && return ((safeeval(a) for a in x.args)...,)
4146
return x
4247
end
48+
recover(::Nothing) = nothing
4349
function recover(x::Vector)
4450
length(x) == 2 || throw(ArgumentError("Expecting a vector of length 2"))
4551
typename = x[1]::String
4652
fields = x[2]::Dict
4753
startswith(typename, "BenchmarkTools.") &&
4854
(typename = typename[(sizeof("BenchmarkTools.") + 1):end])
49-
T = SUPPORTED_TYPES[Symbol(typename)]
55+
T = LOWERED_TO_SUPPORTED_TYPES[Symbol(typename)]
5056
fc = fieldcount(T)
5157
xs = Vector{Any}(undef, fc)
5258
for i in 1:fc
5359
ft = fieldtype(T, i)
5460
fn = String(fieldname(T, i))
55-
if ft == Union{Nothing,LinuxPerf.Stats}
56-
xsi = if isnothing(fields[fn])
57-
nothing
58-
else
59-
convert(ft, fields[fn])
60-
end
61-
elseif ft <: get(SUPPORTED_TYPES, nameof(ft), Union{})
61+
if ft == Union{Nothing, LinuxPerf.Stats} || ft in SUPPORTED_TYPES
6262
xsi = recover(fields[fn])
63+
elseif ft == Vector{LinuxPerf.ThreadStats}
64+
xsi = recover.(fields[fn])
65+
elseif ft == Vector{Vector{LinuxPerf.Counter}}
66+
xsi = [[recover(c) for c in t] for t in fields[fn]]
6367
else
6468
xsi = convert(ft, fields[fn])
6569
end
@@ -120,7 +124,7 @@ function save(io::IO, args...)
120124
"in the order it appears in the input."
121125
)
122126
continue
123-
elseif !(arg isa get(SUPPORTED_TYPES, nameof(typeof(arg)), Union{}))
127+
elseif typeof(arg) SUPPORTED_TYPES
124128
throw(ArgumentError("Only BenchmarkTools types can be serialized."))
125129
end
126130
push!(goodargs, arg)

0 commit comments

Comments
 (0)