Created
December 30, 2017 12:49
-
-
Save evetion/2b57d6105cca39b2d3c6ef670a5cc393 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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