Hello!
Background
I’m fairly new to julia and love it’s potential, but one thing always seems to slow me down. I write scripts almost exclusively (executables with #!/path/to/julia at the top), and they’re oh-so-very-slow as soon as a package gets involved.
For example, I’m creating a CLI program and am using ArgParse for that. I have this very simple program:
#!/usr/local/bin/julia
using ArgParse
function args_parse()
s = ArgParseSettings()
@add_arg_table s begin
"arg1"
help = "a positional argument"
required = true
end
return parse_args(s)
end
function main()
parsed_args = args_parse()
println("Parsed args:")
for (arg,val) in parsed_args
println(" $arg => $val")
end
end
main()
Here’s what I get when I time a run:
[andromodon@yogie cliProject]$ time /opt/julia/julia-1.2.0/bin/julia ./cliProgram.jl
required argument arg1 was not provided
usage: cliProgram.jl arg1
real 0m4.300s
user 0m4.324s
sys 0m0.299s
4 seconds!!! If this is in my inner dev loop, which I kinda want it to be able to be, my project would take months instead of weeks to complete. I know there are well known work-arounds (like never closing julia), but those aren’t ideal. Even my end user shouldn’t end up having to wait 4 seconds for the program to parse their command line arguments.
Problem
So, after some googling, I found that PackageCompiler helps in many circumstances. The thing is I can’t get it to work either.
Here’s my setup script:
#!/usr/local/bin/julia
#This script installs julia dependencies, as needed.
using Pkg
Pkg.add(PackageSpec(name="ArgParse", version= "0.6.2"))
Pkg.build("PackageCompiler")
using PackageCompiler
using ArgParse
#Make loading ArgParse faster (hopefully):
compile_incremental(:ArgParse, force=true)
Running that gives this:
[andromodon@yogie cliProject]$ /opt/julia/julia-1.2.0/bin/julia ./setup.jl
Updating registry at `~/.julia/registries/General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Resolving package versions...
Updating `~/.julia/environments/v1.2/Project.toml`
[no changes]
Updating `~/.julia/environments/v1.2/Manifest.toml`
[no changes]
Building LibCURL ────────→ `~/.julia/packages/LibCURL/lWJxD/deps/build.log`
Building WinRPM ─────────→ `~/.julia/packages/WinRPM/Y9QdZ/deps/build.log`
Building PackageCompiler → `~/.julia/packages/PackageCompiler/CJQcs/deps/build.log`
[ Info: Registered package ArgParse, using already given UUID: c7e460c6-2fb9-53a9-8c5b-16f535851c63
Updating registry at `~/.julia/registries/General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Resolving package versions...
Updating `~/.julia/packages/PackageCompiler/CJQcs/packages/ArgParse/Project.toml`
[34da2185] + Compat v2.2.0
[b718987f] + TextWrap v0.3.0
Updating `~/.julia/packages/PackageCompiler/CJQcs/packages/ArgParse/Manifest.toml`
[34da2185] + Compat v2.2.0
[b718987f] + TextWrap v0.3.0
[2a0f44e3] + Base64
[ade2ca70] + Dates
[8bb1440f] + DelimitedFiles
[8ba89e20] + Distributed
[b77e0a4c] + InteractiveUtils
[76f85450] + LibGit2
[8f399da3] + Libdl
[37e2e46d] + LinearAlgebra
[56ddb016] + Logging
[d6f4376e] + Markdown
[a63ad114] + Mmap
[44cfe95a] + Pkg
[de0858da] + Printf
[3fa0cd96] + REPL
[9a3f8284] + Random
[ea8e919c] + SHA
[9e88b42a] + Serialization
[1a1011a3] + SharedArrays
[6462fe0b] + Sockets
[2f01184e] + SparseArrays
[10745b16] + Statistics
[8dfed614] + Test
[cf7118a7] + UUIDs
[4ec0a83e] + Unicode
Resolving package versions...
Updating `~/.julia/packages/PackageCompiler/CJQcs/packages/ArgParse/Project.toml`
[9b87118b] + PackageCompiler v0.6.4
[44cfe95a] + Pkg
Updating `~/.julia/packages/PackageCompiler/CJQcs/packages/ArgParse/Manifest.toml`
[9e28174c] + BinDeps v0.8.10
[b99e7846] + BinaryProvider v0.5.8
[e1450e63] + BufferedStreams v1.0.0
[0862f596] + HTTPClient v0.2.1
[b27032c2] + LibCURL v0.5.2
[522f3ed2] + LibExpat v0.5.0
[2ec943e9] + Libz v1.0.0
[9b87118b] + PackageCompiler v0.6.4
[30578b45] + URIParser v0.4.0
[c17dfb99] + WinRPM v0.4.2
Activating environment at `~/.julia/packages/PackageCompiler/CJQcs/packages/ArgParse/Project.toml`
ERROR: LoadError: `ArgParse` is a direct dependency, but does not appear in the manifest. If you intend `ArgParse` to be a direct dependency, run `Pkg.resolve()` to populate the manifest. Otherwise, remove `ArgParse` with `Pkg.rm("ArgParse")`. Finally, run `Pkg.instantiate()` again.
Stacktrace:
[1] pkgerror(::String, ::Vararg{String,N} where N) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Pkg/src/Types.jl:112
[2] #instantiate#81(::Nothing, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(Pkg.API.instantiate), ::Pkg.Types.Context) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Pkg/src/API.jl:472
[3] instantiate at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Pkg/src/API.jl:461 [inlined]
[4] #instantiate#80 at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Pkg/src/API.jl:458 [inlined]
[5] instantiate() at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Pkg/src/API.jl:458
[6] top-level scope at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/sysimg/run_julia_code.jl:6
[7] include at ./boot.jl:328 [inlined]
[8] include_relative(::Module, ::String) at ./loading.jl:1094
[9] include(::Module, ::String) at ./Base.jl:31
[10] exec_options(::Base.JLOptions) at ./client.jl:295
[11] _start() at ./client.jl:464
in expression starting at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/sysimg/run_julia_code.jl:6
ERROR: LoadError: failed process: Process(`/opt/julia/julia-1.2.0/bin/julia --compile=all --optimize=0 -g1 --trace-compile=/home/andromodon/.julia/packages/PackageCompiler/CJQcs/packages/precompile_tmp.jl --history-file=yes --code-coverage=none --inline=yes --math-mode=ieee --handle-signals=yes --warn-overwrite=no --compile=yes --depwarn=yes --cpu-target=native --track-allocation=none --sysimage-native-code=yes --sysimage=/opt/julia/julia-1.2.0/lib/julia/sys.so -g1 --compiled-modules=yes --optimize=2 /home/andromodon/.julia/packages/PackageCompiler/CJQcs/sysimg/run_julia_code.jl`, ProcessExited(1)) [1]
Stacktrace:
[1] pipeline_error at ./process.jl:813 [inlined]
[2] #run#536(::Bool, ::typeof(run), ::Cmd) at ./process.jl:728
[3] run at ./process.jl:726 [inlined]
[4] #run_julia#1 at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/src/compiler_flags.jl:225 [inlined]
[5] #run_julia at ./none:0 [inlined]
[6] snoop(::Symbol, ::String, ::String, ::String, ::Bool, ::Array{Any,1}) at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/src/snooping.jl:33
[7] (::getfield(PackageCompiler, Symbol("##35#37")){Array{Any,1},Tuple{Symbol},Dict{Any,Any},String,Dict{String,Array{Dict{String,Any},1}}})(::IOStream) at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/src/snooping.jl:123
[8] #open#312(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(open), ::getfield(PackageCompiler, Symbol("##35#37")){Array{Any,1},Tuple{Symbol},Dict{Any,Any},String,Dict{String,Array{Dict{String,Any},1}}}, ::String, ::Vararg{String,N} where N) at ./iostream.jl:375
[9] open at ./iostream.jl:373 [inlined]
[10] #snoop_packages#34 at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/src/snooping.jl:109 [inlined]
[11] #snoop_packages at ./none:0 [inlined]
[12] #compile_incremental#63 at /home/andromodon/.julia/packages/PackageCompiler/CJQcs/src/incremental.jl:176 [inlined]
[13] (::getfield(PackageCompiler, Symbol("#kw##compile_incremental")))(::NamedTuple{(:force,),Tuple{Bool}}, ::typeof(compile_incremental), ::Symbol) at ./none:0
[14] top-level scope at /home/andromodon/tmp/cliProject/setup.jl:13
[15] include at ./boot.jl:328 [inlined]
[16] include_relative(::Module, ::String) at ./loading.jl:1094
[17] include(::Module, ::String) at ./Base.jl:31
[18] exec_options(::Base.JLOptions) at ./client.jl:295
[19] _start() at ./client.jl:464
in expression starting at /home/andromodon/tmp/cliProject/setup.jl:13
I’m stuck and am not quite sure to do. I read some threads about changing a line in a package or something but I shouldn’t have to edit packages myself to get a basic CLI working quickly with julia. What am I missing??
BTW, I’m using Julia 1.2 since when I was using 1.3 I suffered from this issue.
Thanks for your help.