Skip to content

Instantly share code, notes, and snippets.

@evetion
Created December 30, 2017 12:49
Show Gist options
  • Save evetion/2b57d6105cca39b2d3c6ef670a5cc393 to your computer and use it in GitHub Desktop.
Save evetion/2b57d6105cca39b2d3c6ef670a5cc393 to your computer and use it in GitHub Desktop.
using BenchmarkTools, Compat
using StructIO
# Definitions
@io struct TwoUInt64s
x::UInt64
y::Int64
end
function read_generic_array(io::IOBuffer, t::Type{TwoUInt64s})
args = [read(io, fieldtype(t, i)) for i = 1:@compat fieldcount(t)]
t(args...)
end
function read_generic_tuple(io::IOBuffer, t::Type{TwoUInt64s})
args = (read(io, fieldtype(t, i)) for i = 1:@compat fieldcount(t))
t(args...)
end
function read_written_out(io::IOBuffer, t::Type{TwoUInt64s})
x = read(io, UInt64)
y = read(io, Int64)
t(x, y)
end
function generate_read(T::Type)
fc = @compat fieldcount(T)
types = [fieldtype(T, i) for i = 1:fc]
# Create unpack function expression
function_expression = :(function read_generated(io::IO, t::Type{$T}) end)
# Create Type call expression and add parameters
type_expression = :(($T)())
for t in types
read_expression = :(read(io, $t))
append!(type_expression.args, 0) # dummy
type_expression.args[end] = read_expression
end
# Replace empty function body with Type call
function_expression.args[2] = type_expression
eval(function_expression)
end
generate_read(TwoUInt64s)
# A thousand structs
const n = 10^3
const io = IOBuffer(rand!(Array{UInt8}(16*n)));
println("Using StructIO:")
function a()
seekstart(io)
for _ in 1:n
unpack(io, TwoUInt64s)
end
end
@btime a()
println("Using read_generic_array:")
function b()
seekstart(io)
for _ in 1:n
read_generic_array(io, TwoUInt64s)
end
end
@btime b()
println("Using read_generic_tuple:")
function c()
seekstart(io)
for _ in 1:n
read_generic_tuple(io, TwoUInt64s)
end
end
@btime c()
println("Using read_written_out:")
function d()
seekstart(io)
for _ in 1:n
read_written_out(io, TwoUInt64s)
end
end
@btime d()
println("Using generated_read:")
function e()
seekstart(io)
for _ in 1:n
read_generated(io, TwoUInt64s)
end
end
@btime e()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment