Speed up compilation #1636
Replies: 4 comments 7 replies
-
I suspect StaticArrays is too convenient not to use, but you should strive to narrow the number of different types you compile for. Plotting generates about 1000 new MethodInstances in StaticArrays, of which the following array-types appear: 42-element Vector{Any}:
Point3{Int64} (alias for Point{3, Int64})
SArray{Tuple{3}, Point{_A, T}, 1, 3} where {_A, T<:Real}
StaticVector (alias for StaticArray{Tuple{N}, T, 1} where {N, T})
Point{3, Float32}
StaticArray
Vec2{Float64} (alias for Vec{2, Float64})
MVector{2} (alias for MArray{Tuple{2}, _A, 1, 2} where _A)
SMatrix{4, 4, _A, 16} where _A (alias for SArray{Tuple{4, 4}, _A, 2, 16} where _A)
MVector{3, Float32} (alias for MArray{Tuple{3}, Float32, 1, 3})
Vec2{Int32} (alias for Vec{2, Int32})
GeometryBasics.NgonFace{S, Int64} where S
MMatrix{3, 2, Float32, 6} (alias for MArray{Tuple{3, 2}, Float32, 2, 6})
Point3{Float64} (alias for Point{3, Float64})
SMatrix{3, 1, Float32, 3} (alias for SArray{Tuple{3, 1}, Float32, 2, 3})
Vec3{Bool} (alias for Vec{3, Bool})
Vector{Point{3, Float32}} (alias for Array{Point{3, Float32}, 1})
SMatrix{2, 2, Float32, 4} (alias for SArray{Tuple{2, 2}, Float32, 2, 4})
Vec2{LinRange{Float32, Int64}} (alias for Vec{2, LinRange{Float32, Int64}})
SizedVector{2, Float32, Vector{Float32}} (alias for SizedArray{Tuple{2}, Float32, 1, 1, Array{Float32, 1}})
Point2 (alias for Point{2})
Point2{Float64} (alias for Point{2, Float64})
SizedVector{3, Point{3, Float32}, Vector{Point{3, Float32}}} (alias for SizedArray{Tuple{3}, Point{3, Float32}, 1, 1, Array{Point{3, Float32}, 1}})
AbstractArray
Vec{4, Float32}
GeometryBasics.NgonFace{3, GeometryBasics.OffsetInteger{-1, UInt32}}
MMatrix{3, 3, Float32, 9} (alias for MArray{Tuple{3, 3}, Float32, 2, 9})
Point2{Bool} (alias for Point{2, Bool})
Vec2{Int64} (alias for Vec{2, Int64})
Vec2 (alias for Vec{2})
SMatrix{2, 8, Float64, 16} (alias for SArray{Tuple{2, 8}, Float64, 2, 16})
Vec2{Bool} (alias for Vec{2, Bool})
Vec
SMatrix{4, 4, Float32, 16} (alias for SArray{Tuple{4, 4}, Float32, 2, 16})
StaticArray{S, T, 1} where {T, S<:Tuple}
Point{2, Float32}
SVector{3, Float32} (alias for SArray{Tuple{3}, Float32, 1, 3})
GeometryBasics.NgonFace{S, Bool} where S
SVector{2, Point{2, Float32}} (alias for SArray{Tuple{2}, Point{2, Float32}, 1, 2})
Vec{3, Float32}
Vec2{LinRange{Float64, Int64}} (alias for Vec{2, LinRange{Float64, Int64}})
Vector{ObserverFunction} (alias for Array{Observables.ObserverFunction, 1})
Vec{2, Float32} The abstractly-typed ones are from poor inference and obviously not instantiated. |
Beta Was this translation helpful? Give feedback.
-
At least through inference, not always including codegen. Let's look at your abstract inference and its cost: $ julia -q --startup-file=no --project --compiled-modules=no # don't use the *.ji files so we can witness inference of *everything*
julia> using SnoopCompileCore, Makie
julia> tinf = @snoopi_deep plot(rand(10));
julia> using SnoopCompile
julia> list = filter(flatten(tinf)) do it
mi = Core.MethodInstance(it)
mi.def isa Method && parentmodule(mi.def.module) == Makie
end; # get just those MethodInstances from methods defined in Makie or its submodules
julia> alist = filter(list) do it
mi = Core.MethodInstance(it)
!isconcretetype(mi.specTypes)
end # this has some false alarms (`Type{T}` is called non-concrete even if `T` is) but many are correct
1890-element Vector{SnoopCompileCore.InferenceTiming}:
InferenceTiming: 0.000013/0.000013 on MakieCore.used_attributes(::Type{MakieCore.Text{Tuple{Vector{String}}}}, ::Vector{String})
InferenceTiming: 0.000013/0.000013 on MakieCore.used_attributes(::Type{MakieCore.Text{Tuple{Vector{Tuple{AbstractString, Point{2, Float32}}}}}}, ::Vector{Tuple{AbstractString, Point{2, Float32}}})
InferenceTiming: 0.000013/0.000013 on MakieCore.used_attributes(::Type{MakieCore.Text{Tuple{}}})
InferenceTiming: 0.000013/0.000013 on MakieCore.used_attributes(::Type{Mesh{Tuple{Vector{Point{2, Float32}}, Matrix{Int64}}}}, ::Vector{Point{2, Float32}}, ::Matrix{Int64})
InferenceTiming: 0.000013/0.000013 on MakieCore.used_attributes(::Type{MakieCore.Text{Tuple{Vector{Makie.GlyphCollection}}}}, ::Vector{Makie.GlyphCollection})
InferenceTiming: 0.000013/0.000013 on MakieCore.used_attributes(::Type{Mesh{Tuple{GeometryBasics.HyperRectangle{2, Int64}}}}, ::GeometryBasics.HyperRectangle{2, Int64})
InferenceTiming: 0.000014/0.000014 on MakieCore.used_attributes(::Type{Mesh{_A}} where _A, ::Vararg{Any})
InferenceTiming: 0.000014/0.000014 on MakieCore.used_attributes(::Type{Scatter{_A}} where _A, ::Vararg{Any})
InferenceTiming: 0.000014/0.000014 on MakieCore.used_attributes(::Type{MakieCore.Text{Tuple{Makie.GlyphCollection}}}, ::Makie.GlyphCollection)
InferenceTiming: 0.000014/0.000014 on MakieCore.used_attributes(::Type{Lines{Tuple{Vector{Point2{Float64}}}}}, ::Vector{Point2{Float64}})
InferenceTiming: 0.000015/0.000015 on MakieCore.used_attributes(::Type{LineSegments{_A}} where _A, ::Vararg{Any})
InferenceTiming: 0.000015/0.000015 on MakieCore.used_attributes(::Type{Lines{_A}} where _A, ::Vararg{Any})
InferenceTiming: 0.000015/0.000015 on MakieCore.plottype(::Type{Scatter{_A}} where _A, ::Type{Combined{Makie.stairs}})
InferenceTiming: 0.000015/0.000015 on MakieCore.used_attributes(::Type{MakieCore.Text{_A}} where _A, ::Vararg{Any})
InferenceTiming: 0.000015/0.000015 on MakieCore.plottype(::Type{LineSegments{Tuple{Vector{Point{2, Float32}}}}}, ::Vararg{Any})
InferenceTiming: 0.000015/0.000015 on MakieCore.plottype(::Type{Scatter{Tuple{Vector{Float64}}}}, ::Vararg{Any})
InferenceTiming: 0.000015/0.000015 on MakieCore.used_attributes(::Type{Scatter{Tuple{Vector{Float64}}}}, ::Vector{Float64})
InferenceTiming: 0.000015/0.000015 on MakieCore.plottype(::Type{MakieCore.Text{Tuple{Makie.GlyphCollection}}}, ::Vararg{Any})
InferenceTiming: 0.000016/0.000016 on MakieCore.plottype(::Type{MakieCore.Text{Tuple{Vector{String}}}}, ::Vararg{Any})
InferenceTiming: 0.000016/0.000016 on MakieCore.plottype(::Type{Mesh{_A}} where _A, ::Type{Combined{Makie.stairs}})
InferenceTiming: 0.000016/0.000016 on MakieCore.used_attributes(::Type{Scatter{_A}} where _A, ::StatsBase.ECDF)
InferenceTiming: 0.000016/0.000016 on MakieCore.plottype(::Type{MakieCore.Text{Tuple{Vector{Tuple{AbstractString, Point{2, Float32}}}}}}, ::Vararg{Any})
InferenceTiming: 0.000016/0.000016 on MakieCore.plottype(::Type{Lines{Tuple{Vector{Point{2, Float32}}}}}, ::Vararg{Any})
InferenceTiming: 0.000016/0.000016 on MakieCore.plottype(::Type{LineSegments{_A}} where _A, ::Type{Combined{Makie.stairs}})
⋮
InferenceTiming: 0.010409/0.091547 on Makie.attribute_per_char(::AbstractString, ::Any)
InferenceTiming: 0.010563/0.020409 on (::Makie.MakieLayout.var"#109#110"{Observable{GeometryBasics.HyperRectangle{2, Int64}}})(::GeometryBasics.HyperRectangle{2, Float32}, ::GeometryBasics.HyperRectangle{2, Float32}, ::Any)
InferenceTiming: 0.010763/0.019954 on Makie.var"#convert_arguments#777"(::Symbol, convert_arguments::typeof(convert_arguments), ::Type{<:Combined{Makie.qqnorm}}, ::String)
InferenceTiming: 0.010778/0.012973 on Makie.var"#convert_arguments#776"(::Any, convert_arguments::typeof(convert_arguments), ::Type{<:Combined{Makie.qqplot}}, ::Vector{Point{2, Float32}}, ::Matrix{Int64})
InferenceTiming: 0.011452/0.032388 on (::Makie.MakieLayout.var"#255#286"{Scene})(::GeometryBasics.HyperRectangle{2, Float32}, ::Any, ::Any, ::Any)
InferenceTiming: 0.012015/0.018670 on Makie.attribute_per_char(::Any, ::Any)
InferenceTiming: 0.014850/0.014850 on (::Makie.var"#132#134")(::Any)
InferenceTiming: 0.015878/0.017869 on MakieCore.plot!(::Combined, ::Type, ::Attributes, ::Tuple{Observable}, ::Observable)
InferenceTiming: 0.016627/0.041253 on Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, Observable, NTuple{37, Symbol}, NamedTuple{(:endpoints, :limits, :flipped, :ticklabelrotation, :ticklabelalign, :labelsize, :labelpadding, :ticklabelpad, :labelvisible, :label, :labelfont, :ticklabelfont, :ticklabelcolor, :labelcolor, :tickalign, :ticklabelspace, :ticks, :tickformat, :ticklabelsvisible, :ticksvisible, :spinevisible, :spinecolor, :spinewidth, :trimspine, :ticklabelsize, :ticksize, :flip_vertical_label, :reversed, :tickwidth, :tickcolor, :minorticksvisible, :minortickalign, :minorticksize, :minortickwidth, :minortickcolor, :minorticks, :scale), Tuple{Observable{Tuple{Point{2, Float32}, Point{2, Float32}}}, Observable{Tuple{Float32, Float32}}, Observable{Bool}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Bool}, Observable{Symbol}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
InferenceTiming: 0.016631/0.016631 on Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, _A, NTuple{37, Symbol}, NamedTuple{names, T}} where {_A, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
InferenceTiming: 0.017916/0.066169 on Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, Observable, NTuple{36, Symbol}, NamedTuple{(:endpoints, :limits, :flipped, :ticklabelrotation, :ticklabelalign, :labelsize, :labelpadding, :ticklabelpad, :labelvisible, :label, :labelfont, :ticklabelfont, :ticklabelcolor, :labelcolor, :tickalign, :ticklabelspace, :ticks, :tickformat, :ticklabelsvisible, :ticksvisible, :spinevisible, :spinecolor, :spinewidth, :ticklabelsize, :trimspine, :ticksize, :reversed, :tickwidth, :tickcolor, :minorticksvisible, :minortickalign, :minorticksize, :minortickwidth, :minortickcolor, :minorticks, :scale), Tuple{Observable{Tuple{Point{2, Float32}, Point{2, Float32}}}, Observable{Tuple{Float32, Float32}}, Observable{Bool}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Bool}, Observable{Symbol}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
InferenceTiming: 0.023030/1.614263 on Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, _A, NTuple{36, Symbol}, NamedTuple{names, T}} where {_A, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
InferenceTiming: 0.023146/0.405696 on Makie.ecdf_xvalues(::StatsBase.ECDF, ::Any)
InferenceTiming: 0.026120/0.348611 on Makie.MakieLayout.default_attributes(::Type{Axis}, ::Scene)
InferenceTiming: 0.026905/0.026905 on Makie.to_ndim(::Type{T} where T<:Union{Tuple{Vararg{ET, N}}, StaticArrays.StaticVector{N, ET}}, ::Vec{4, Float32}, ::Float64) where {N, ET}
InferenceTiming: 0.027972/0.027972 on Makie.to_ndim(::Type{T} where T<:Union{Tuple{Vararg{ET, N}}, StaticArrays.StaticVector{N, ET}}, ::Point{3, Float32}, ::Int64) where {N, ET}
InferenceTiming: 0.028953/0.028953 on Makie.to_ndim(::Type{T} where T<:Union{Tuple{Vararg{ET, N}}, StaticArrays.StaticVector{N, ET}}, ::Point{2, Float32}, ::Float64) where {N, ET}
InferenceTiming: 0.034308/0.035234 on Makie.MakieLayout.var"#layoutable#251"(nothing::Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}()::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, layoutable::typeof(Makie.MakieLayout.layoutable), ::Type{Axis}, ::Figure)
InferenceTiming: 0.034493/0.053073 on Makie.MakieLayout.var"#layoutable#251"(::Any, ::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}}, layoutable::typeof(Makie.MakieLayout.layoutable), ::Type{Axis}, ::Figure)
InferenceTiming: 0.037808/0.057584 on Makie.glyph_collection(::String, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
InferenceTiming: 0.039908/0.352839 on Makie.glyph_collection(::AbstractString, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
InferenceTiming: 0.046154/0.090162 on Makie.MakieLayout.get_cycle_for_plottype(::Attributes, ::Type)
InferenceTiming: 0.053564/6.353569 on Makie.MakieLayout.var"#layoutable#251"(nothing::Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}()::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, layoutable::typeof(Makie.MakieLayout.layoutable), ::Type{Axis}, ::Figure)
InferenceTiming: 0.069274/0.069274 on Makie.to_ndim(::Type{<:Union{Tuple{Vararg{ET, N}}, StaticArrays.StaticVector{N, ET}}}, ::Point{2, Float32}, ::Int64) where {N, ET} From this list, you can see:
and so on. One of the best things you could do to improve inferrability is to eliminate Step 1: find all of Makie's modules and submodules (you may want to also do this for CairoMakie, GLMakie, etc) julia> using MethodAnalysis
julia> mmods = Module[]
Module[]
julia> visit(Makie) do item
item isa Module || return false
parentmodule(item) == Makie || return false
push!(mmods, item)
return true
end
julia> mmods
6-element Vector{Module}:
Makie
Makie.ContoursHygiene
Makie.Formatters
Makie.Keyboard
Makie.MakieLayout
Makie.Mouse Step 2: collect all MethodInstances julia> allmis = Core.MethodInstance[];
julia> for m in mmods
append!(allmis, methodinstances(m))
end Step 3: find all that have a variable inferred as julia> boxmis = filter(allmis) do mi
try
srcs = Base.code_typed_by_type(mi.specTypes)
for (ci, rt) in srcs
(any(==(Core.Box), ci.slottypes) || any(==(Core.Box), ci.ssavaluetypes)) && return true
end
return false
catch
return false
end
end
85-element Vector{Core.MethodInstance}:
MethodInstance for Makie.var"#Scene#92"(::Nothing, ::Events, ::Bool, ::Function, ::Nothing, ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Nothing, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Nothing, ::Events, ::Bool, ::typeof(identity), ::Nothing, ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Nothing, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Observable{GeometryBasics.HyperRectangle{2, Int64}}, ::Events, ::Bool, ::Function, ::Nothing, ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Scene, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Observable{GeometryBasics.HyperRectangle{2, Int64}}, ::Events, ::Bool, ::typeof(identity), ::Nothing, ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Scene, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Observable{GeometryBasics.HyperRectangle{2, Int64}}, ::Events, ::Bool, ::Function, ::typeof(cam3d!), ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Scene, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Observable{GeometryBasics.HyperRectangle{2, Int64}}, ::Events, ::Bool, ::typeof(identity), ::typeof(cam3d!), ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Scene, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Nothing, ::Events, ::Bool, ::Function, ::typeof(campixel!), ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Nothing, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Nothing, ::Events, ::Bool, ::typeof(identity), ::typeof(campixel!), ::EmptyCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Nothing, ::Observable{Bool}, ::SSAO, ::MakieCore.Automatic, ::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::Type{Scene})
MethodInstance for Makie.var"#Scene#92"(::Union{Nothing, Observable{GeometryBasics.HyperRectangle{2, Int64}}}, ::Events, ::Bool, ::Any, ::Union{Nothing, Function, Camera}, ::AbstractCamera, ::Transformation, ::Vector{AbstractPlot}, ::Attributes, ::Vector{Scene}, ::Vector{AbstractScreen}, ::Any, ::Any, ::Any, ::Any, ::Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Scene})
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Any}, ::Attributes, ::Vector{Float64})
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Scatter{Tuple{Vector{Float64}}}}, ::Attributes, ::Tuple{Observable{Vector{Float64}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{LineSegments{Tuple{Vector{Point{2, Float32}}}}}, ::Attributes, ::Tuple{Observable{Vector{Point{2, Float32}}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::MakieCore.Text{Tuple{String}}, ::Type{MakieCore.Text{Tuple{Makie.GlyphCollection}}}, ::Attributes, ::Tuple{Observable{Makie.GlyphCollection}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Lines{Tuple{Vector{Point{2, Float32}}}}}, ::Attributes, ::Tuple{Observable{Vector{Point{2, Float32}}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{MakieCore.Text{Tuple{Vector{Tuple{AbstractString, Point{2, Float32}}}}}}, ::Attributes, ::Tuple{Observable{Vector{Tuple{AbstractString, Point{2, Float32}}}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::MakieCore.Text{Tuple{Vector{Tuple{AbstractString, Point{2, Float32}}}}}, ::Type{MakieCore.Text{Tuple{Vector{String}}}}, ::Attributes, ::Tuple{Observable{Vector{String}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::MakieCore.Text{Tuple{Vector{String}}}, ::Type{MakieCore.Text{Tuple{Vector{Makie.GlyphCollection}}}}, ::Attributes, ::Tuple{Observable{Vector{Makie.GlyphCollection}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Lines{Tuple{Vector{Point2{Float64}}}}}, ::Attributes, ::Tuple{Observable{Vector{Point2{Float64}}}}, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Any}, ::Attributes, ::Any, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Any}, ::Attributes, ::Type, ::Attributes, ::Any, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Combined, ::Type{Any}, ::Attributes, ::Type, ::Attributes, ::Any, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Combined, ::Type{Any}, ::Attributes, ::Any, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Any}, ::Attributes, ::Type, ::Vararg{Any})
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Any}, ::Attributes, ::Vararg{Any})
⋮
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Lines}, ::Attributes)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{MakieCore.Text}, ::Attributes, ::Any)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{MakieCore.Text}, ::Attributes)
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{LineSegments}, ::Attributes, ::Observable{Vector{Point{2, Float32}}})
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(plot!), ::Scene, ::Type{Mesh}, ::Attributes, ::Observable{GeometryBasics.HyperRectangle{2, Int64}})
MethodInstance for Makie.var"#plot!#150"(::Base.Pairs, ::typeof(plot!), ::Scene, ::Union{Type{Any}, Type{<:AbstractPlot}}, ::Attributes, ::Any, ::Any)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, Observable, NTuple{36, Symbol}, NamedTuple{(:endpoints, :limits, :flipped, :ticklabelrotation, :ticklabelalign, :labelsize, :labelpadding, :ticklabelpad, :labelvisible, :label, :labelfont, :ticklabelfont, :ticklabelcolor, :labelcolor, :tickalign, :ticklabelspace, :ticks, :tickformat, :ticklabelsvisible, :ticksvisible, :spinevisible, :spinecolor, :spinewidth, :ticklabelsize, :trimspine, :ticksize, :reversed, :tickwidth, :tickcolor, :minorticksvisible, :minortickalign, :minorticksize, :minortickwidth, :minortickcolor, :minorticks, :scale), TupleYou can fix that by m{Observable{Tuple{Point{2, Float32}, Point{2, Float32}}}, Observable{Tuple{Float32, Float32}}, Observable{Bool}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Bool}, Observable{Symbol}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, Observable, NTuple{37, Symbol}, NamedTuple{(:endpoints, :limits, :flipped, :ticklabelrotation, :ticklabelalign, :labelsize, :labelpadding, :ticklabelpad, :labelvisible, :label, :labelfont, :ticklabelfont, :ticklabelcolor, :labelcolor, :tickalign, :ticklabelspace, :ticks, :tickformat, :ticklabelsvisible, :ticksvisible, :spinevisible, :spinecolor, :spinewidth, :trimspine, :ticklabelsize, :ticksize, :flip_vertical_label, :reversed, :tickwidth, :tickcolor, :minorticksvisible, :minortickalign, :minorticksize, :minortickwidth, :minortickcolor, :minorticks, :scale), Tuple{Observable{Tuple{Point{2, Float32}, Point{2, Float32}}}, Observable{Tuple{Float32, Float32}}, Observable{Bool}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Bool}, Observable{Symbol}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, _A, NTuple{37, Symbol}, NamedTuple{names, T}} where {_A, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, _A, NTuple{36, Symbol}, NamedTuple{names, T}} where {_A, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.attribute_per_char(::AbstractString, ::Any)
MethodInstance for Makie.attribute_per_char(::Any, ::Any)
MethodInstance for Makie.attribute_per_char(::String, ::Any)
MethodInstance for Makie.attribute_per_char(::String, ::FreeTypeAbstraction.FTFont)
MethodInstance for Makie.attribute_per_char(::String, ::Float32)
MethodInstance for Makie.attribute_per_char(::String, ::Quaternionf)
MethodInstance for Makie.attribute_per_char(::String, ::ColorTypes.RGBA{Float32})
MethodInstance for Makie.attribute_per_char(::String, ::Int64)
MethodInstance for Makie.boundingbox(::Vector{Makie.GlyphCollection}, ::Vector{Point{3, Float32}}, ::Quaternionf)
MethodInstance for Makie.draw_axis3d(::Any, ::Any, ::Any, ::Any, ::Any, ::Vararg{Any})
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, Observable, NTuple{36, Symbol}, NamedTuple{(:endpoints, :limits, :flipped, :ticklabelrotation, :ticklabelalign, :labelsize, :labelpadding, :ticklabelpad, :labelvisible, :label, :labelfont, :ticklabelfont, :ticklabelcolor, :labelcolor, :tickalign, :ticklabelspace, :ticks, :tickformat, :ticklabelsvisible, :ticksvisible, :spinevisible, :spinecolor, :spinewidth, :ticklabelsize, :trimspine, :ticksize, :reversed, :tickwidth, :tickcolor, :minorticksvisible, :minortickalign, :minorticksize, :minortickwidth, :minortickcolor, :minorticks, :scale), Tuple{Observable{Tuple{Point{2, Float32}, Point{2, Float32}}}, Observable{Tuple{Float32, Float32}}, Observable{Bool}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Bool}, Observable{Symbol}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, Observable, NTuple{37, Symbol}, NamedTuple{(:endpoints, :limits, :flipped, :ticklabelrotation, :ticklabelalign, :labelsize, :labelpadding, :ticklabelpad, :labelvisible, :label, :labelfont, :ticklabelfont, :ticklabelcolor, :labelcolor, :tickalign, :ticklabelspace, :ticks, :tickformat, :ticklabelsvisible, :ticksvisible, :spinevisible, :spinecolor, :spinewidth, :trimspine, :ticklabelsize, :ticksize, :flip_vertical_label, :reversed, :tickwidth, :tickcolor, :minorticksvisible, :minortickalign, :minorticksize, :minortickwidth, :minortickcolor, :minorticks, :scale), Tuple{Observable{Tuple{Point{2, Float32}, Point{2, Float32}}}, Observable{Tuple{Float32, Float32}}, Observable{Bool}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Bool}, Observable{Symbol}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}, Observable{Any}}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, _A, NTuple{37, Symbol}, NamedTuple{names, T}} where {_A, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene)
MethodInstance for Makie.MakieLayout.var"#LineAxis#179"(::Base.Pairs{Symbol, _A, NTuple{36, Symbol}, NamedTuple{names, T}} where {_A, names, T<:Tuple{Vararg{Any, N}}}, ::Type{Makie.MakieLayout.LineAxis}, ::Scene) Fixing these is often reasonably straightforward; there's an example in #1634 (see the julia> using Cthulhu
julia> mi = boxmis[end-7]
MethodInstance for Makie.attribute_per_char(::String, ::ColorTypes.RGBA{Float32})
julia> descend(mi; optimize=false, iswarn=true)
attribute_per_char(string, attribute) in Makie at /home/tim/.julia/packages/Makie/14tKQ/src/layouting/layouting.jl:9
Variables
#self#::Core.Const(Makie.attribute_per_char)
string::String
attribute::ColorTypes.RGBA{Float32}
#669::Union{}
i::Core.Box
n_words::Int64
Body::Base.Generator{String, Makie.var"#665#666"{ColorTypes.RGBA{Float32}}}
@ /home/tim/.julia/packages/Makie/14tKQ/src/layouting/layouting.jl:10 within `attribute_per_char`
1 ─ Core.NewvarNode(:(#669))
│ (i = Core.Box())
│ (n_words = 0)
│ @ /home/tim/.julia/packages/Makie/14tKQ/src/layouting/layouting.jl:11 within `attribute_per_char`
│ %4 = (attribute isa Makie.AbstractVector)::Core.Const(false)
└── goto #2 if not %4
@ /home/tim/.julia/packages/Makie/14tKQ/src/layouting/layouting.jl:26 within `attribute_per_char`
2 ─ %6 = Makie.one_attribute_per_char(attribute, string)::Base.Generator{String, Makie.var"#665#666"{ColorTypes.RGBA{Float32}}}
└── return %6
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [o]ptimize, [w]arn, [h]ide type-stable statements, [d]ebuginfo, [r]emarks, [i]nlining costs, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
• %2 = Box()::Core.Box
%6 = one_attribute_per_char(::ColorTypes.RGBA{Float32},::String)::Base.Generator{String, Makie.var"#665#666"{ColorTypes.RGBA{Float32}}}
↩ This shows the You need to be on at least Julia 1.7 for that Cthulhu demo to work. If you're unfamiliar with Cthulhu, one nice thing is you can type |
Beta Was this translation helpful? Give feedback.
-
Update: I've spent quite a lot of time by now to improve inference, caching of inference, remove slow to compile code and refactor a couple of constructs, that don't directly influence compilation times, but make it harder to find the slow code. This pretty much is the result of working on most of the low hanging fruits. I'm hoping to find a couple more places where I can remove the number of specializations. The whole Axis code is also slow to compile. After those refactors, I plan a phase of brute force improvements, where I go through every function and try to improve compile times and inference caching, to squeeze out some more seconds for all backends... |
Beta Was this translation helpful? Give feedback.
-
Final ReportMost improvements have made it to the latest release, but there are still further improvements in #1918 #2056 and #2046.
More detailed plots of all the recorded benchmarks: CairoMakieGLMakieA few key take aways:
To keep regressions low, quite a bit of time was spend on a CI job that benchmarks compile times for Makie and all backends (the report looks like this). Compared to the last update (thread above) we're now at 3.12x (prev 2.4x) TTFP and with using 2.6x (prev 1.9x) faster. |
Beta Was this translation helpful? Give feedback.
-
Discussion about how to improve Makie's compile times!
Current state
To keep things simple we only analyse the following snippet at the moment:
Time spent on Makie#master:
Some more data from using ENABLE_TIMINGS:
For
using CairoMakie
:For
using CairoMakie; save("test.png", scatter(1:4))
:So quite a bit is spent in inference, but also in module loading.
A majority seems to be spent in Base, StaticArrays and GeometryBasics.
We can cut the inference time to almost 0 by caching more of inference.
@timholy made amazing progress at improving Julia's inference caching in JuliaLang/julia#43990.
State with teh/cache_external
Install Instructions:
Results (after precompilation):
This gives us a net win of around 7s, so a whopping 20% improvement.
With
ENABLE_TIMINGS
, we can see that inference time is almost at 0 now:So once teh/cache_external lands, we should concentrate mainly on reducing LLVM compile times and and add more precompile statements to make sure that most of Makie is covered and inference is actually cached.
Reducing LLVM compile times
(time spent on teh/cache_external)
A lot of the remaining time is still spend in StaticArrays & GeometryBasics, which isn't surprising since most of that code is high performance geometry code. But the code is also needlessly complicated to generalize to any Static vector like, which makes it very hard to compile on top of things.
We need to cut down on types and specializations wherever we can, so I propose we drastically simplifying the static Point/Vec/Mat code in GeometryBasics and move away from StaticArrays.
Right now we use Vec/Point/Tuple/SVector in lots of places for the same thing, which means we recompile similar code multiple times.
Simplifying that code should also decrease load times, since StaticArrays is generating lots of inference results and code.
Finally we should go through the worst to compile functions and inspect each one of them and see if we can simplify or despecialize the functions.
So the main tasks we need to do to speed up Makie compile times are:
Beta Was this translation helpful? Give feedback.
All reactions