KristofferC / OhMyREPL.jl

Syntax highlighting and other enhancements for the Julia REPL
https://kristofferc.github.io/OhMyREPL.jl/latest/
Other
749 stars 56 forks source link

add precompilation #288

Closed tfiers closed 1 year ago

tfiers commented 1 year ago

Closes #242, #286

The precompile.jl file I made seems fragile (I'm especially concerned by the gensyms). But it works nicely: the delay-on-first-character and delay on fzf init (ctrl-r) are much shorter now. EDIT: even though shorter, there is still a delay. This should be reduced further with native code caching in next Julia releases

Package load time is now about 0.5 seconds (Julia 1.8.1, Win11)

KristofferC commented 1 year ago

Nice, we need to be a bit careful with the var"#25#26" symbols. These are automatically generated and their name can change due to different things and if that symbol is no longer available, there will be an error and no one can suddenly use the package.

tfiers commented 1 year ago

I agree. More robust would be to use @precompile_all_calls from SnoopPreCompile; but I had no idea how to use OhMyREPL programmatically; hence why I went this manual way

Quick fix would be to just comment out all the gensym lines

tfiers commented 1 year ago

..but even without the var"# lines this is fragile: any method or signature changes in any of the deps, and it breaks

tfiers commented 1 year ago

Is there a way to automate REPL typing?

Or alternatively, do you know what would be a good @precompile_all_calls load? (I'm not very familiar with the internals of OhMyREPL)

tfiers commented 1 year ago

EDIT: even though shorter, there is still a delay. This should be reduced further with native code caching in next Julia releases

Interestingly, this still-there-delay is only present in a new julia session. It's not present in the session where you load and precompile OhMyREPL for the first time.

(This is cause only llvm IR is cached I presume, not native instructions)

We could eliminate the delay-on-first char in every session (for Julia ≤1.8 at least) by calling precompile in __init__ (Or rather, we don't eliminate it, but we move it to package load time).

KristofferC commented 1 year ago

any method or signature changes in any of the deps, and it breaks

Not really because precompile doesn't error if a signature doesn't exist, it just returns false.

KristofferC commented 1 year ago

but I had no idea how to use OhMyREPL programmatically; hence why I went this manual way

Yeah, it's a bit tricky. You have to basically set up a "fake REPL" that you load OhMyREPL into. I can experiment a bit.

One issue is that we are overwriting some REPL functions though. That will always cause some slowness since the new functions have to be compiled and I don't think that can be cached.

tfiers commented 1 year ago

Trying this fork on WSL (Ubuntu), precompilation fails due to the gensyms, as expected:

julia> using OhMyREPL
[ Info: Precompiling OhMyREPL [5fb14364-9ced-5910-84b2-373655c76a03]
ERROR: LoadError: UndefVarError: `#25#26` not defined
Stacktrace:
 [1] getproperty(x::Module, f::Symbol)
   @ Base ./Base.jl:31
 [2] top-level scope
   @ ~/.julia/dev/OhMyREPL/src/precompile.jl:35

In the following commit, I commented out all gensym lines from precompilation, and it works both on Windows and Ubuntu now.

The speedup on first-character due to precompilation is still great (almost instant), even without the gensym lines (In fact I didn't notice a difference with or without them).

tfiers commented 1 year ago

@KristofferC , all var"# gensym lines have been commented out, and the package compiles both on linux and Windows

Ok to merge now?

(I can remove the commented lines to save some bytes, if you'd like)

KristofferC commented 1 year ago

Can you try with https://github.com/KristofferC/OhMyREPL.jl/pull/296. It should generate these automatically.