# Precompile a script?

**URL:** https://discourse.julialang.org/t/precompile-a-script/5364
**Category:** General Usage
**Tags:** question
**Created:** [August 13, 2017, 9:29pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364 "2017-08-13T21:29:49Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [August 13, 2017, 9:29pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/1 "2017-08-13T21:29:49Z")

</div>

Is there a way to precompile a script, so that I can execute it in batch fast?

---

<div class="post-metadata">

### Author: ![mindbound](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mindbound/32/587_2.png) [@mindbound](https://discourse.julialang.org/u/mindbound)
#### Post date: [August 13, 2017, 9:44pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/2 "2017-08-13T21:44:36Z")

</div>

To quote the [official docs](https://docs.julialang.org/en/stable/manual/modules/#Module-initialization-and-precompilation-1),

> To create an incremental precompiled module file, add ` __precompile__ ()` at the top of your module file (before the module starts). This will cause it to be automatically compiled the first time it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`.

---

<div class="post-metadata">

### Author: ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)
#### Post date: [August 13, 2017, 10:16pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/3 "2017-08-13T22:16:59Z")

</div>

What about a script, not a module?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 14, 2017, 1:49am UTC](https://discourse.julialang.org/t/precompile-a-script/5364/4 "2017-08-14T01:49:16Z")

</div>

Put the main computational functions (hopefully you are using functions and not one long Matlab-style script full of globals) of the script into a module.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [August 14, 2017, 7:20am UTC](https://discourse.julialang.org/t/precompile-a-script/5364/5 "2017-08-14T07:20:36Z")

</div>

However, it may not give you the hoped for speed-up, see e.g. [https://github.com/carlobaldassi/ArgParse.jl/issues/37](https://github.com/carlobaldassi/ArgParse.jl/issues/37)

---

<div class="post-metadata">

### Author: ![davidavdav](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidavdav/32/1065_2.png) [@davidavdav](https://discourse.julialang.org/u/davidavdav)
#### Post date: [October 7, 2019, 12:42pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/6 "2019-10-07T12:42:19Z")

</div>

Hello,

Just wondering–-why is the issue in ArgParse closed? Argparse still is very slow IMHO. I’ve tried to move my argparsing code in a module that is precompiled and everything, and it still takes over 4 seconds or so to parse three arguments

---

<div class="post-metadata">

### Author: ![zachmatson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zachmatson/32/9397_2.png) [@zachmatson](https://discourse.julialang.org/u/zachmatson)
#### Post date: [May 19, 2020, 7:04pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/7 "2020-05-19T19:04:11Z")

</div>

I don’t know if you’re still having this issue, but I just created a new argument parsing module that might help with that somewhat. [GitHub - zachmatson/ArgMacros.jl: Fast, flexible, macro-based, Julia package for parsing command line arguments.](https://github.com/zachmatson/ArgMacros.jl)  
Still in the middle of the three-day waiting period for adding Julia packages to the registry but can be added from GitHub still right now.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [May 19, 2020, 7:36pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/8 "2020-05-19T19:36:35Z")

</div>

The `stable` docs link is broken, just so you know. Not sure if intended.

---

<div class="post-metadata">

### Author: ![zachmatson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zachmatson/32/9397_2.png) [@zachmatson](https://discourse.julialang.org/u/zachmatson)
#### Post date: [May 19, 2020, 7:50pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/9 "2020-05-19T19:50:51Z")

</div>

Yes, it will work once the package is approved into the Julia registry and the first “stable” release gets tagged. Thank you for the heads up though.

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [May 19, 2020, 9:53pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/10 "2020-05-19T21:53:48Z")

</div>

For me (and good to know, try `-O1`, even `-O0` sometimes faster for short-running scripts):

```julia
$ julia -O0 --startup-file=no
julia> @time using ArgMacros
  0.321002 seconds (1.04 M allocations: 48.524 MiB, 2.98% gc time)

or without -O0 on julia-1.5-DEV, with using my PR where I use -O1:

(@v1.5) pkg> add https://github.com/zachmatson/ArgMacros.jl#5a9b3a5

```

[https://github.com/JuliaLang/julia/issues/35932#issue-620548735](https://github.com/JuliaLang/julia/issues/35932#issue-620548735)

---

<div class="post-metadata">

### Author: ![davidavdav](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidavdav/32/1065_2.png) [@davidavdav](https://discourse.julialang.org/u/davidavdav)
#### Post date: [May 20, 2020, 7:46am UTC](https://discourse.julialang.org/t/precompile-a-script/5364/11 "2020-05-20T07:46:29Z")

</div>

Thanks! I find that [ArgMacros](https://github.com/zachmatson/ArgMacros.jl/blob/master/docs/src/index.md).jl is much faster than `ArgParse` and therefore finally makes it feasible to start using Julia for small scripts. When combining with [JSObjectLiteral](https://github.com/davidavdav/JSObjectLiteral.jl) (I never bothered to register this it seems) you can write

```julia
using ArgMacros
using JSObjectLiteral

function parseargs()
    @beginarguments begin
        @argumentrequired String first "-f" "--first"
        @argumentdefault Number π second "-s" "--second"
    end

    return @js { first, second }
end

args = parseargs() ## Dict{String,Any}("second" => π,"first" => "hi")
println(args)
println(@js(args.first), ' ', args["second"])

```

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [May 20, 2020, 12:34pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/12 "2020-05-20T12:34:09Z")

</div>

Actually I see:

```julia
$ ~/julia-1.6.0-DEV-8f512f3f6d/bin/julia -O3 # 10 days old master
julia> @time using ArgMacros
  0.021667 seconds (23.77 k allocations: 1.637 MiB)

```

similar time for any (or no) optimization setting (and that’s not with my PR). It seems we have much to look forward to for Julia 1.6, and maybe already this fast in 1.5, as my nightly I used is 24 days old.

---

<div class="post-metadata">

### Author: ![zachmatson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zachmatson/32/9397_2.png) [@zachmatson](https://discourse.julialang.org/u/zachmatson)
#### Post date: [May 20, 2020, 2:20pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/13 "2020-05-20T14:20:33Z")

</div>

Didn’t think much about usage outside of a main function (type stability and making sure the compiler knows the types was one of the big goals with `ArgMacros`) but I guess maybe Julia is just at the point right now where it makes more sense not to use one for short scripts. Might add untyped versions of all of the macros when I finish a version 1.0 if this could be useful, or a different version of `@beginarguments` that disables typing.

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [May 20, 2020, 4:51pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/14 "2020-05-20T16:51:43Z")

</div>

> [@zachmatson](#):
>
> Julia is just at the point right now where it makes more sense not to use one for short scripts

I think it does make sense, just try `julia -O0` if it’s very short running.

> [@Rethinking optimization, lower ok for all Julia code (for e.g. faster startup) as a default?](https://discourse.julialang.org/t/rethinking-optimization-lower-ok-for-all-julia-code-for-e-g-faster-startup-as-a-default/39843):
>
> Clearly lower optimization wouldn’t be faster always, or we would always use lower levels. As of version 1.5 it doesn’t need to be one global setting, and since we can tune I suggest changing the default. E.g. for some real-world 27 line script of mine (that uses three packages, e.g. CSV.jl) runs for 20 sec. (17 sec. on julia-1.6-dev) on Julia’s defaults that are 45% slower, and I’ve gotten 3.7x the speed, with non-default, lowest (lower than -O0 only; with --compile=min additionally), optimizat…

An interpreter can also in practice (for short-running code) be faster, and I haven’t looked enough at [Home · JuliaInterpreter.jl](https://juliadebug.github.io/JuliaInterpreter.jl/stable/) it may be for other purposes (only for debug?).

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [May 24, 2020, 11:22pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/15 "2020-05-24T23:22:11Z")

</div>

For [EDIT: some; e.g. very short-running] scripts I would really run with these defaults, that have the fastest startup e.g. over 5x faster, and not too bad performance:

```julia
$ ~/julia-1.6.0-DEV-8f512f3f6d/bin/julia -O0 --compile=min --startup-file=no

julia> @time (s = 0; for i in 1:100000 s+=i end)
  0.167227 seconds (398.95 k allocations: 7.614 MiB) # not too bad, slower than 0.005288 seconds without default

```

Such default can e.g. enable 0.28 sec. time-to-first plot.

[https://github.com/heliosdrm/GRUtils.jl/issues/61](https://github.com/heliosdrm/GRUtils.jl/issues/61)

Jeff reminded me of this undocumented option above my answer here:  
[https://github.com/timholy/Revise.jl/pull/484#issuecomment-633146603](https://github.com/timholy/Revise.jl/pull/484#issuecomment-633146603)

[https://github.com/JuliaLang/julia/issues/36017](https://github.com/JuliaLang/julia/issues/36017)

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [May 25, 2020, 12:13pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/16 "2020-05-25T12:13:26Z")

</div>

> [@Palli](#):
>
> and not too bad performance:

I think it is a bit unfair to say that: Standrad julia:

```julia
julia> s = rand(10^6);

julia> @time sum(s);
  0.000364 seconds (1 allocation: 16 bytes)

```

`--compile-min`:

```julia
julia> s = rand(10^6);

julia> @time sum(s);
  3.618843 seconds (7.46 M allocations: 114.119 MiB, 0.20% gc time)

```

It’s good to know the option exist but I don’t think it can be recommended as a “I would really run with these defaults”-option.

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [May 25, 2020, 3:38pm UTC](https://discourse.julialang.org/t/precompile-a-script/5364/17 "2020-05-25T15:38:33Z")

</div>

You took out my context “For scripts”, for me, implying short-running code [EDIT: FYI: I’ve seen `--compile=min` be 3.7x faster, than Julia’s defaults, on a 30 sec, 12-line (excl. dependencies) script: [Faster startup by PallHaraldsson · Pull Request #383 · JuliaInterop/RCall.jl · GitHub](https://github.com/JuliaInterop/RCall.jl/pull/383#issuecomment-634624944)]. You can’t have the same good default for (very) long running (HPC) code, and short running scripts. There will always be trade-offs, at least two good defaults depending; and I admit, I see this third option `--compile=min` ~~is only good for very short running scripts~~ , after looking more into it. It still _might_ be a good default while developing, before your optimization phase.

I was trying to find a good balance, minimizing compilation time, going towards Python-defaults, but I see I went way beyond that, with a similar loop there faster than with `compile=min`.

I tried “dogfooding” on one of my Julia scripts I made for work, where Julia’s default is 32% slower, by 5.3 sec than `-O0` (that is also faster than `-O1`), or 44% slower on 1.6.0-DEV, by 5.86 sec, while the other option:

```julia
$ time ~/julia-1.3.1/bin/julia --startup-file=no fenics-db.jl

real	0m21,663s

$ time ~/julia-1.3.1/bin/julia --startup-file=no --compile=min fenics-db.jl

real	11m59,102s

```

Ouch. Still the header (what I put in using.jl) of the script is faster, and for some short running scripts the two second gain there might not be lost later in some script:

```julia
using CodecZlib # a wrapper, probably -O0 ok.
using CSV # highly tuned code. Probably optimization, shouldn't go lower, maybe it should selectively go higher and/or JLL?
using DataFrames

$ time ~/julia-1.6.0-DEV-8f512f3f6d/bin/julia --startup-file=no using.jl 

real	0m3,678s

$ time ~/julia-1.6.0-DEV-8f512f3f6d/bin/julia --startup-file=no --compile=min using.jl 

real	0m1,616s

```

In my ~/.julia/config/startup.jl I have only:

```julia
@time using Revise
println("Revise speed test") # to remind me how slow it is loading, why you should use --startup-file=no when benchmarking

```

I occasionally see very slow loading of even (this) one package, here I had forgotten to exclude it:

```julia

$ time julia fenics-db.jl
 31.301598 seconds (2.85 M allocations: 106.293 MiB, 0.50% gc time)
Revise speed test

```

“good to know the option exist”

Yes, why I added the Julia issue to add it to --help, but I’m getting skeptical, maybe it should remain under the other undocumented:

```julia
$ ~/julia-1.6.0-DEV-8f512f3f6d/bin/julia --help-hidden
julia [switches] -- [programfile] [args...]
 --compile={yes|no|all|min}Enable or disable JIT compiler, or request exhaustive compilation
[..]

```

---

<div class="post-metadata">

### Author: ![F-YF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/f-yf/32/17363_2.png) [@F-YF](https://discourse.julialang.org/u/F-YF)
#### Post date: [August 5, 2022, 11:52am UTC](https://discourse.julialang.org/t/precompile-a-script/5364/18 "2022-08-05T11:52:29Z")

</div>

Can scripts be precompiled into Cache files? Include the cache files before calling the script, thereby skipping the script precompilation.

> [@mindbound](#):
>
> Alternatively, you can manually call `Base.compilecache(modulename)`.
