From 11c5680d5620b0b64420055e8474a2b8cf757010 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 4 Dec 2018 14:17:14 -0500 Subject: [PATCH] speed up (de)serialization of Base bits types in abstract containers (#30221) helps #30148 --- stdlib/Serialization/src/Serialization.jl | 50 +++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/stdlib/Serialization/src/Serialization.jl b/stdlib/Serialization/src/Serialization.jl index 0e0886fa11f23..41fd2ccf34d56 100644 --- a/stdlib/Serialization/src/Serialization.jl +++ b/stdlib/Serialization/src/Serialization.jl @@ -90,7 +90,7 @@ function sertag(@nospecialize(v)) end return Int32(-1) end -desertag(i::Int32) = TAGS[i] +desertag(i::Int32) = @inbounds(TAGS[i]) # tags >= this just represent themselves, their whole representation is 1 byte const VALUE_TAGS = sertag(()) @@ -102,6 +102,7 @@ const EMPTYTUPLE_TAG = sertag(()) const TUPLE_TAG = sertag(Tuple) const SIMPLEVECTOR_TAG = sertag(SimpleVector) const SYMBOL_TAG = sertag(Symbol) +const INT8_TAG = sertag(Int8) const ARRAY_TAG = sertag(Array) const EXPR_TAG = sertag(Expr) const MODULE_TAG = sertag(Module) @@ -337,7 +338,7 @@ end function serialize_mod_names(s::AbstractSerializer, m::Module) p = parentmodule(m) - if p === m + if p === m || m === Base key = Base.root_module_key(m) serialize(s, key.uuid === nothing ? nothing : key.uuid.value) serialize(s, Symbol(key.name)) @@ -586,6 +587,13 @@ function serialize(s::AbstractSerializer, n::Int64) nothing end +for i in 0:13 + tag = Int32(INT8_TAG + i) + ty = TAGS[tag] + (ty === Int32 || ty === Int64) && continue + @eval serialize(s::AbstractSerializer, n::$ty) = (writetag(s.io, $tag); write(s.io, n); nothing) +end + serialize(s::AbstractSerializer, ::Type{Bottom}) = write_as_tag(s.io, BOTTOM_TAG) function serialize(s::AbstractSerializer, u::UnionAll) @@ -748,6 +756,9 @@ function handle_deserialize(s::AbstractSerializer, b::Int32) return unwrap_unionall(tname.wrapper) elseif b == OBJECT_TAG t = deserialize(s) + if t === Missing + return missing + end return deserialize(s, t) elseif b == REF_OBJECT_TAG slot = s.counter; s.counter += 1 @@ -788,8 +799,36 @@ function handle_deserialize(s::AbstractSerializer, b::Int32) read(s.io, UInt8) end return deserialize(s) + elseif b == INT8_TAG + return read(s.io, Int8) + elseif b == INT8_TAG+1 + return read(s.io, UInt8) + elseif b == INT8_TAG+2 + return read(s.io, Int16) + elseif b == INT8_TAG+3 + return read(s.io, UInt16) + elseif b == INT32_TAG + return read(s.io, Int32) + elseif b == INT8_TAG+5 + return read(s.io, UInt32) + elseif b == INT64_TAG + return read(s.io, Int64) + elseif b == INT8_TAG+7 + return read(s.io, UInt64) + elseif b == INT8_TAG+8 + return read(s.io, Int128) + elseif b == INT8_TAG+9 + return read(s.io, UInt128) + elseif b == INT8_TAG+10 + return read(s.io, Float16) + elseif b == INT8_TAG+11 + return read(s.io, Float32) + elseif b == INT8_TAG+12 + return read(s.io, Float64) + elseif b == INT8_TAG+13 + return read(s.io, Char) end - t = desertag(b) + t = desertag(b)::DataType if t.mutable && length(t.types) > 0 # manual specialization of fieldcount slot = s.counter; s.counter += 1 push!(s.pending_refs, slot) @@ -949,6 +988,11 @@ function deserialize_array(s::AbstractSerializer) A = Array{elty, length(dims)}(undef, dims) s.table[slot] = A sizehint!(s.table, s.counter + div(length(A),4)) + deserialize_fillarray!(A, s) + return A +end + +function deserialize_fillarray!(A::Array{T}, s::AbstractSerializer) where {T} for i = eachindex(A) tag = Int32(read(s.io, UInt8)::UInt8) if tag != UNDEFREF_TAG