diff --git a/src/serialization.jl b/src/serialization.jl index 80851fd2..0ad6f62b 100644 --- a/src/serialization.jl +++ b/src/serialization.jl @@ -2,35 +2,16 @@ const VERSIONS = Dict("Julia" => string(VERSION), "BenchmarkTools" => string(BENCHMARKTOOLS_VERSION)) # TODO: Add any new types as they're added -const supported_types = [Benchmark, BenchmarkGroup, Parameters, TagFilter, Trial, +const SUPPORTED_TYPES = [Benchmark, BenchmarkGroup, Parameters, TagFilter, Trial, TrialEstimate, TrialJudgement, TrialRatio] -for T in supported_types +for T in SUPPORTED_TYPES @eval function JSON.lower(x::$T) S = typeof(x) # T could be a UnionAll [string(S), Dict(fieldname($T, i) => getfield(x, i) for i = 1:fieldcount($T))] end end -mutable struct ParametersPreV006 - seconds::Float64 - samples::Int - evals::Int - overhead::Int - gctrial::Bool - gcsample::Bool - time_tolerance::Float64 - memory_tolerance::Float64 -end - -mutable struct TrialPreV006 - params::Parameters - times::Vector{Int} - gctimes::Vector{Int} - memory::Int - allocs::Int -end - function recover(x::Vector) length(x) == 2 || throw(ArgumentError("Expecting a vector of length 2")) typename = x[1]::String @@ -41,7 +22,7 @@ function recover(x::Vector) for i = 1:fc ft = fieldtype(T, i) fn = String(fieldname(T, i)) - xs[i] = if ft in supported_types + xs[i] = if ft in SUPPORTED_TYPES recover(fields[fn]) else convert(ft, fields[fn]) @@ -50,20 +31,22 @@ function recover(x::Vector) T(xs...) end +function badext(filename) + noext, ext = splitext(filename) + msg = if ext == ".jld" + "JLD serialization is no longer supported. Benchmarks should now be saved in\n" * + "JSON format using `save(\"$noext\".json, args...)` and loaded from JSON using\n" * + "using `load(\"$noext\".json, args...)`. You will need to convert existing\n" * + "saved benchmarks to JSON in order to use them with this version of BenchmarkTools." + else + "Only JSON serialization is supported." + end + throw(ArgumentError(msg)) +end + function save(filename::AbstractString, args...) + endswith(filename, ".json") || badext(filename) isempty(args) && throw(ArgumentError("Nothing to save")) - if !endswith(filename, ".json") - noext, ext = splitext(filename) - msg = if ext == ".jld" - "JLD serialization is no longer supported. Benchmarks should now be saved\n" * - "in JSON format using `save(\"$noext\".json, args...)`. You will need to\n" * - "convert existing saved benchmarks to JSON in order to deserialize them with\n" * - "this version of BenchmarkTools." - else - "Only JSON serialization is supported. Use `save(\"$noext.json\", args...)`." - end - throw(ArgumentError(msg)) - end goodargs = Any[] for arg in args if arg isa String @@ -71,7 +54,7 @@ function save(filename::AbstractString, args...) "will be ignored and the object will be serialized in the order it appears " * "in the input.") continue - elseif !any(T->arg isa T, supported_types) + elseif !any(T->arg isa T, SUPPORTED_TYPES) throw(ArgumentError("Only BenchmarkTools types can be serialized.")) end push!(goodargs, arg) @@ -83,61 +66,16 @@ function save(filename::AbstractString, args...) end function load(filename::AbstractString, args...) - if !endswith(filename, ".json") - noext, ext = splitext(filename) - msg = if ext == ".jld" - "JLD deserialization is no longer supported. Benchmarks should now be saved\n" * - "in JSON format using `save(\"$noext\".json, args...)`. You will need to\n" * - "convert existing saved benchmarks to JSON in order to deserialize them with\n" * - "this version of BenchmarkTools." - else - "Only JSON deserialization is supported. Use `load(\"$noext.json\", args...)`." - end - throw(ArgumentError(msg)) - end + endswith(filename, ".json") || badext(filename) if !isempty(args) throw(ArgumentError("Looking up deserialized values by name is no longer supported, " * "as names are no longer saved.")) end parsed = open(JSON.parse, filename, "r") if !isa(parsed, Vector) || length(parsed) != 2 || !isa(parsed[1], Dict) || !isa(parsed[2], Vector) - error("Unexpected JSON format. Was this file produced by BenchmarkTools?") + error("Unexpected JSON format. Was this file originally written by BenchmarkTools?") end versions = parsed[1]::Dict values = parsed[2]::Vector map!(recover, values, values) end - -#function JLD.readas(p::ParametersPreV006) -# return Parameters(p.seconds, p.samples, p.evals, Float64(p.overhead), p.gctrial, -# p.gcsample, p.time_tolerance, p.memory_tolerance) -#end -# -#function JLD.readas(t::TrialPreV006) -# new_times = convert(Vector{Float64}, t.times) -# new_gctimes = convert(Vector{Float64}, t.gctimes) -# return Trial(t.params, new_times, new_gctimes, t.memory, t.allocs) -#end -# -#function save(filename, args...) -# JLD.save(filename, VERSION_KEY, VERSIONS, args...) -# JLD.jldopen(filename, "r+") do io -# JLD.addrequire(io, BenchmarkTools) -# end -# return nothing -#end -# -#@inline function load(filename, args...) -# # no version-based rules are needed for now, we just need -# # to check that version information exists in the file. -# if JLD.jldopen(file -> JLD.exists(file, VERSION_KEY), filename, "r") -# result = JLD.load(filename, args...) -# else -# JLD.translate("BenchmarkTools.Parameters", "BenchmarkTools.ParametersPreV006") -# JLD.translate("BenchmarkTools.Trial", "BenchmarkTools.TrialPreV006") -# result = JLD.load(filename, args...) -# JLD.translate("BenchmarkTools.Parameters", "BenchmarkTools.Parameters") -# JLD.translate("BenchmarkTools.Trial", "BenchmarkTools.Trial") -# end -# return result -#end diff --git a/test/SerializationTests.jl b/test/SerializationTests.jl index 6051f2e8..a21de731 100644 --- a/test/SerializationTests.jl +++ b/test/SerializationTests.jl @@ -4,7 +4,7 @@ using Compat using Compat.Test using BenchmarkTools -eq(x::T, y::T) where {T<:Union{BenchmarkTools.supported_types...}} = +eq(x::T, y::T) where {T<:Union{BenchmarkTools.SUPPORTED_TYPES...}} = all(i->eq(getfield(x, i), getfield(y, i)), 1:fieldcount(T)) eq(x::T, y::T) where {T} = isapprox(x, y)