Skip to content

Commit

Permalink
a few latency improvements using SnoopCompile (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kristoffer Carlsson authored Aug 31, 2020
1 parent 2ccd5c1 commit 7709e39
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/PGFPlotsX.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,7 @@ include("tikzpicture.jl")
include("tikzdocument.jl")
include("requires.jl")
include("build.jl")
include("precompile_PGFPlotsX.jl")
_precompile_()

end # module
11 changes: 9 additions & 2 deletions src/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,20 @@ function prockey(key)
error("Invalid pgf option $key")
end

if !isdefined(Base, :mapany)
mapany(f, itr) = map!(f, Vector{Any}(undef, length(itr)::Int), itr) # convenient for Expr.args
else
using Base: mapany
end


function procmap(d)
if @capture(d, f_(xs__))
return :($f($(map(procmap, xs)...)))
return :($f($(mapany(procmap, xs)...)))
elseif !@capture(d, {xs__})
return d
else
return :($(Options)($(map(prockey, xs)...); print_empty = true))
return :($(Options)($(mapany(prockey, xs)...); print_empty = true))
end
end

Expand Down
65 changes: 65 additions & 0 deletions src/precompile_PGFPlotsX.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const __bodyfunction__ = Dict{Method,Any}()

# Find keyword "body functions" (the function that contains the body
# as written by the developer, called after all missing keyword-arguments
# have been assigned values), in a manner that doesn't depend on
# gensymmed names.
# `mnokw` is the method that gets called when you invoke it without
# supplying any keywords.
function __lookup_kwbody__(mnokw::Method)
function getsym(arg)
isa(arg, Symbol) && return arg
@assert isa(arg, GlobalRef)
return arg.name
end

f = get(__bodyfunction__, mnokw, nothing)
if f === nothing
fmod = mnokw.module
# The lowered code for `mnokw` should look like
# %1 = mkw(kwvalues..., #self#, args...)
# return %1
# where `mkw` is the name of the "active" keyword body-function.
ast = Base.uncompressed_ast(mnokw)
if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
callexpr = ast.code[end-1]
if isa(callexpr, Expr) && callexpr.head == :call
fsym = callexpr.args[1]
if isa(fsym, Symbol)
f = getfield(fmod, fsym)
elseif isa(fsym, GlobalRef)
if fsym.mod === Core && fsym.name === :_apply
f = getfield(mnokw.module, getsym(callexpr.args[2]))
elseif fsym.mod === Core && fsym.name === :_apply_iterate
f = getfield(mnokw.module, getsym(callexpr.args[3]))
else
f = getfield(fsym.mod, fsym.name)
end
else
f = missing
end
else
f = missing
end
else
f = missing
end
__bodyfunction__[mnokw] = f
end
return f
end

function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
Base.precompile(Tuple{Core.kwftype(typeof(PGFPlotsX.Type)),NamedTuple{(:print_empty,), Tuple{Bool}},Type{PGFPlotsX.Options},Pair{String, Nothing},Pair{String, Nothing}})
Base.precompile(Tuple{Type{Axis},PGFPlotsX.Options,Plot})
Base.precompile(Tuple{Type{Coordinates},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(display),PGFPlotsX.PGFPlotsXDisplay,Axis})
Base.precompile(Tuple{typeof(print_tex),IOStream,TikzPicture,TikzDocument})
Base.precompile(Tuple{typeof(procmap),Expr})
let fbody = try __lookup_kwbody__(which(PGFPlotsX.save, (String,TikzDocument,))) catch missing end
if !ismissing(fbody)
Base.precompile(fbody, (Bool,PGFPlotsX.LaTeXEngine,Vector{String},Int64,Bool,typeof(PGFPlotsX.save),String,TikzDocument,))
end
end
end

0 comments on commit 7709e39

Please sign in to comment.