I’m trying to write a compiler in Julia, and I’m getting very bad performance. Because it’s a multi-stage compiler, most of the code is just the same function for different types of ast.
I made sure most of the structs and methods deal with concrete types, i.e. not abstract, but that doesn’t seem to help.
I ran the profiler, and it looks like the vast majority of the time is spent inside Julia’s type inference. Here’s the profiler output:
julia> Profile.print(format=:flat, sortedby=:count)
... (removed the top, because it's a huge list) ...
1761 C:\code\preql\src\main.jl 461 eval_ast(::main.State, ::ast.Projection)
1844 .\compiler\optimize.jl 169 optimize(::Core.Compiler.OptimizationState, ::Any)
1899 .\compiler\typeinfer.jl 33 typeinf(::Core.Compiler.InferenceState)
3039 .\compiler\typeinfer.jl 568 typeinf_ext(::Core.MethodInstance, ::Core.Compiler.Params)
3050 .\compiler\typeinfer.jl 599 typeinf_ext(::Core.MethodInstance, ::UInt64)
3316 C:\code\preql\src\main.jl 516 eval_pql(::main.State, ::String)
3729 .\compiler\abstractinterpretation.jl 1160 typeinf_local(::Core.Compiler.InferenceState)
6096 .\Base.jl 31 include(::Module, ::String)
6096 .\boot.jl 328 include
6096 .\client.jl 295 exec_options(::Base.JLOptions)
6096 .\loading.jl 1094 include_relative(::Module, ::String)
6097 .\client.jl 464 _start()
11926 .\compiler\abstractinterpretation.jl 1174 typeinf_local(::Core.Compiler.InferenceState)
13326 .\compiler\typeinfer.jl 482 typeinf_edge(::Method, ::Any, ::Core.SimpleVector, ::Core.Compi...
13484 .\compiler\abstractinterpretation.jl 376 abstract_call_method(::Method, ::Any, ::Core.SimpleVector, ::Bo...
13506 .\compiler\abstractinterpretation.jl 93 abstract_call_gf_by_type(::Any, ::Array{Any,1}, ::Any, ::Core.C...
14882 .\compiler\abstractinterpretation.jl 818 abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{An...
15089 .\compiler\abstractinterpretation.jl 847 abstract_eval_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,...
15090 .\compiler\abstractinterpretation.jl 608 abstract_call(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{An...
15625 .\compiler\abstractinterpretation.jl 917 abstract_eval(::Any, ::Array{Any,1}, ::Core.Compiler.InferenceS...
15694 .\compiler\abstractinterpretation.jl 1230 typeinf_nocycle(::Core.Compiler.InferenceState)
15712 .\compiler\typeinfer.jl 12 typeinf(::Core.Compiler.InferenceState)
Why is so much of the time spent in type inference? What approach can I take to fix it?
Again, I’m mostly using non-abstract types, and I’m not even using generics, or any kind of specialized type arithmetic. Most of what I’m doing, I believe, can be easily replicated by a standard OO language.
Is it something I’m doing, or is this a known issue in Julia?
Thanks