3

I am running code shown in this question. I expected it to run faster second and third time (on first run it takes time to compile the code). However, it seems to be taking same amount of time as the first time. How can I make this code run faster?

Edit: I am running the code by giving command on Linux terminal: julia mycode.jl

I tried following instructions in the answer by @Przemyslaw Szufel but got following error:

julia> create_sysimage(["Plots"], sysimage_path="sys_plots.so", precompile_execution_file="precompile_plots.jl")

ERROR: MethodError: no method matching create_sysimage(::Array{String,1}; sysimage_path="sys_plots.so", precompile_execution_file="precompile_plots.jl")
Closest candidates are:
  create_sysimage() at /home/cardio/.julia/packages/PackageCompiler/2yhCw/src/PackageCompiler.jl:462 got unsupported keyword arguments "sysimage_path", "precompile_execution_file"
  create_sysimage(::Union{Array{Symbol,1}, Symbol}; sysimage_path, project, precompile_execution_file, precompile_statements_file, incremental, filter_stdlibs, replace_default, base_sysimage, isapp, julia_init_c_file, version, compat_level, soname, cpu_target, script) at /home/cardio/.julia/packages/PackageCompiler/2yhCw/src/PackageCompiler.jl:462
Stacktrace:
 [1] top-level scope at REPL[25]:1

I am using Julia on Debian Stable Linux: Debian ⛬ julia/1.5.3+dfsg-3

rnso
  • 23,686
  • 25
  • 112
  • 234
  • How do you run this code? Do you do `julia mycode.jl ` each time or are you running it within a single Julia session? – Przemyslaw Szufel Sep 04 '22 at 14:31
  • I am running the code by giving command on Linux terminal: `julia mycode.jl` – rnso Sep 04 '22 at 14:33
  • A couple of other related questions: https://stackoverflow.com/questions/66159138/speeding-up-julia-on-terminal-for-the-second-run https://stackoverflow.com/questions/50608970/if-a-julia-script-is-run-from-the-command-line-does-it-need-to-be-re-compiled-e – Sundar R Sep 04 '22 at 14:41
  • 1
    But I wouldn't recommend the solutions mentioned in the answers there, generally, just see them for the explanation. The solution, in short, is to use the REPL itself to run the code: place your code in functions in your file, and (for small amounts of code like in your previous question) use `Revise.includet`[as described here](https://timholy.github.io/Revise.jl/stable/cookbook/#includet-usage-1). – Sundar R Sep 04 '22 at 14:48

2 Answers2

7

In Julia packages are compiled each time they are run withing a single Julia session. Hence starting a new Julia process means that each time Plots.jl get compiled. This is quite a big package so will take a significant time to compile.

In order to circumvent it, use the PackageCompiler and compile Plots.jl into a static system image that can be used later by Julia

The basic steps include:

using PackageCompiler
create_sysimage(["Plots"], sysimage_path="sys_plots.so", precompile_execution_file="precompile_plots.jl")

After this is done you will need to run your code as:

julia --sysimage sys_plots.so mycode.jl

Similarly you could have added MultivariateStats and RDatasets to the generated sysimage but I do not think they cause any significant delay.

Note that if the subsequent runs are part of your development process (rather than your production system implementation) and you are eg. developing a Julia module than you could rather consider using Revise.jl in the development process rather than precompile the sysimage. Basically, having the sysimage means that you will need to rebuild it each time you update your Julia packages so I would consider this approach rather for production than development (depends on your exact scenario).

Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
  • I get: ERROR: MethodError: no method matching create_sysimage(::Array{String,1}; sysimage_path="sys_plots.so", precompile_execution_file="precompile_plots.jl") – rnso Sep 04 '22 at 16:10
  • I have included full error message in my question above. – rnso Sep 04 '22 at 17:00
  • What `methods(create_sysimage)` is showing you? You should see a line such as `[2] create_sysimage(packages::Union{Nothing, Vector{String}, Vector{Symbol}, Symbol}; ...` – Przemyslaw Szufel Sep 04 '22 at 17:53
  • create_sysimage(::Union{Array{Symbol,1}, Symbol} - As I added in my question above. – rnso Sep 04 '22 at 18:14
  • I do not have Julia 1.5.3 to test. What about trying to use 1.8.0? – Przemyslaw Szufel Sep 04 '22 at 18:32
  • Debian Stable repository has 1.5.3 – rnso Sep 04 '22 at 18:33
  • sure but anything older than 1.6.0 is currently old and supported. Julia is quite a young language that is rapidly changing and package compiler stack is the most complex and advanced feature. – Przemyslaw Szufel Sep 04 '22 at 21:27
  • @mso I also don't have the version you cite (hit: in Linux use the binaries from julialang.org, supersimple to install, rather than the official repos). Looking at the error message the package version you are using seems to ask the package names as Symbols instead of string, e.g. `create_sysimage([:Plots], sysimage_path="sys_plots.so", precompile_execution_file="precompile_plots.jl")`. – Antonello Sep 05 '22 at 11:43
  • 1
    I installed Julia 1.8 and it is much better than the previous version. – rnso Sep 05 '22 at 13:44
  • @Antonello you are right - I did not notice it is a `Symbol`, could help :) – Przemyslaw Szufel Sep 05 '22 at 18:37
  • Compiling Plots to `.so` file placed locally works very well. Can I do the same for my own code file with similar command? Will `create_sysimage(["Mycode"], sysimage_path = "mycode.so", precompile_execution_file="MyCode.jl")` work? – rnso Sep 15 '22 at 13:34
  • 1
    @rnso yes it should be possible - I would try to pack the code to a package, `Pkg.activate` that package and then precompile it. – Przemyslaw Szufel Sep 15 '22 at 14:17
5

I had this problem and almost went back to Python but now I run scripts in the REPL with include. It is much faster this way.

Note: First run will be slow but subsequent runs in the same REPL session will be fast even if the script is edited.

Fedora 36, Julia 1.8.1