Skip to content

Commit

Permalink
Improve precompilability with noninferrable filename
Browse files Browse the repository at this point in the history
After #259, the result of `filename(q)` is not inferrable.
This uses "the kernel trick" to provide a single point where the result
must be inferred, and an `invokelatest` to prevent the abstract signature
from being inferred. It then precompiles the `::String` variant.
Consequently, with respect to latency this should get us back to where
we were before #259.
  • Loading branch information
timholy committed Dec 31, 2020
1 parent 6fd2c3a commit c2fb5b0
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/loadsave.jl
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,18 @@ end
# Handlers for formatted files/streams

for fn in (:load, :loadstreaming, :metadata)
fn_func_name = Symbol(fn, "_filename")
gen2_func_name = Symbol("fileio_", fn)
@eval function $fn(@nospecialize(q::Formatted), @nospecialize(args...); @nospecialize(options...))
Base.invokelatest($fn_func_name, q, filename(q), args...; options...)
end
@eval function $fn_func_name(@nospecialize(q::Formatted), filename, @nospecialize(args...); @nospecialize(options...))
if unknown(q)
isfile(filename(q)) || open(filename(q)) # force systemerror
isfile(filename) || open(filename) # force systemerror
throw(UnknownFormat(q))
end
if q isa File
!isfile(filename(q)) && throw(ArgumentError("No file exists at given path: $(filename(q))"))
!isfile(filename) && throw(ArgumentError("No file exists at given path: $(filename)"))
end
libraries = applicable_loaders(q)
failures = Any[]
Expand All @@ -207,7 +211,7 @@ for fn in (:load, :loadstreaming, :metadata)
push!(failures, (e, q))
end
end
handle_exceptions(failures, "loading $(repr(filename(q)))")
handle_exceptions(failures, "loading $(repr(filename))")
end
end

Expand Down
6 changes: 6 additions & 0 deletions src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ function _precompile_()
@assert precompile(Tuple{typeof(load),File})
@assert precompile(Tuple{typeof(load),Formatted})
@assert precompile(Tuple{typeof(load),String})
@assert precompile(Tuple{typeof(FileIO.load_filename),Formatted,String})
if isdefined(Base, :bodyfunction)
fbody = Base.bodyfunction(which(FileIO.load_filename, (Formatted, String)))
@assert precompile(fbody, (Any, typeof(FileIO.load_filename), Formatted, String))
@assert precompile(fbody, (Any, typeof(FileIO.load_filename), Formatted, String, Vararg{Any,100}))
end

@assert precompile(Tuple{typeof(query),String})
@assert precompile(Tuple{typeof(query),IOStream})
Expand Down

0 comments on commit c2fb5b0

Please sign in to comment.