I do not understand why there is a 30x difference between these two implementations. I guess I am doing some dumb (benchmarking) mistake because the produced LLVM code seems to be equal.
Note that I am using a large buffer to avoid EOF inside the benchmark loop. I could not get it to work with @btime foo(x) setup=(x=IOBuffer(rand(UInt8, 10000)))
as it always throws an EOF error, no matter how large the buffer is.
julia> function foo(io)
out = Vector{Int32}()
sizehint!(out, 100)
for i in 1:100
push!(out, read(io, Int32))
end
out
end
foo (generic function with 2 methods)
julia> function foo(io, T::Type)
out = Vector{T}()
sizehint!(out, 100)
for i in 1:100
push!(out, read(io, T))
end
out
end
foo (generic function with 2 methods)
julia> data = IOBuffer(rand(UInt8, 1000000000));
julia> @btime foo($data);
848.355 ns (2 allocations: 528 bytes)
julia> data = IOBuffer(rand(UInt8, 1000000000));
julia> @btime foo($data, $Int32);
24.893 Îźs (102 allocations: 2.08 KiB)
I looked at the @code_llvm
output of both calls and they seem to be identical, so is this som kind of a benchmarking issue?
simple.llvm
is coming from @code_llvm foo(data)
parametric.llvm
is coming from @code_llvm foo(data, Int32)
â tamasgal@greybox.local:~/tmp/wtf took 3s
â 16:56:31 > diff simple.llvm parametric.llvm
1,2c1,2
< ; @ REPL[45]:2 within `foo'
< define nonnull %jl_value_t addrspace(10)* @japi1_foo_18517(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {
---
> ; @ REPL[44]:2 within `foo'
> define nonnull %jl_value_t addrspace(10)* @japi1_foo_18685(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {
26c26
< ; @ REPL[45]:3 within `foo'
---
> ; @ REPL[44]:3 within `foo'
30c30
< ; @ REPL[45]:5 within `foo'
---
> ; @ REPL[44]:5 within `foo'
170c170
< ; @ REPL[45]:7 within `foo'
---
> ; @ REPL[44]:7 within `foo'
174c174
< ; @ REPL[45]:5 within `foo'
---
> ; @ REPL[44]:5 within `foo'
Any ideas? The performance regression is real in my code, I clearly see a huge difference in allocations and elapsed time when I pass in the types.