Huge difference between passing a type, or using a hardcoded-type (in benchmarks)?

Explicitly forcing specialization on T fixes the issue for me:

julia> function foo(io, ::Type{T}) where {T}
           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)

And, by the way, you want to set evals = 1 in your benchmark code to ensure that the function is only run once per setup call:

julia> @btime foo(x) setup=(x = IOBuffer(rand(UInt8, 1000))) evals=1;
  485.000 ns (2 allocations: 528 bytes)

julia> @btime foo(x, T) setup=(x = IOBuffer(rand(UInt8, 1000)); T=Int32) evals=1;
  486.000 ns (2 allocations: 528 bytes)

Otherwise the function will be evaluated many times per setup call, which is why you’re hitting EOF (ref: BenchmarkTools setup isn't run between each iteration? - #6 by rdeits) .

4 Likes