# Package warmup / SnoopCompile

**URL:** <https://discourse.julialang.org/t/package-warmup-snoopcompile/20266>\
**Category:** General Usage\
**Tags:** precompilation\
**Created:** [January 30, 2019, 10:04am UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266 "2019-01-30T10:04:15Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [January 30, 2019, 10:04am UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/1 "2019-01-30T10:04:15Z")

</div>

Looking at [SnoopCompile.jl](https://discourse.julialang.org/t/can-i-define-a-precompile-sequence/2474) I was wondering whether I could write a simple “hint” file that would pre-compile the standard paths in the program making loading the package a bit slower but hopefully the first call faster. However that’s not really what I observed and I’m not sure why. In fact I even tried to have the exact same call in the warmup and in the first call but with the same result.

What I tried:

```julia
module SomeModule
# ...
include("warmup.jl") # contains "_warmup()_ = some_function(1, 2, 3)"
@show @elapsed _warmup_()
end

```

I was a bit surprised to see that the first call to exactly `some_function(1, 2, 3)` is not much faster. Results as follow to give an idea:

- warmup call ~ 2.2s (`using SomeModule`)
- first\_call ~1.8s (`@elapsed some_function(1, 2, 3)`)
- second\_call ~0.1s (`@elapsed some_function(1, 2, 3)`)

I would have expected the first call to be closer to the second call in terms of time given the “warmup” but I “only” seem to be gaining between 10 and 30%. Why is that the case?

If I remove the “warmup”, the results are

- first call ~2.8s
- second call ~0.1s

This is maybe similar to what was experienced in [this thread about specifying a precompile sequence](https://discourse.julialang.org/t/can-i-define-a-precompile-sequence/2474).

Thanks!

(fwiw, I’m on Julia 1.2, macOS.)

**Edit** , interestingly if I call the `_warmup_` twice in the module, I get

- first warmup 2.2s
- second warmup 1.1s 👀
- first call 2s 👀
- second call 0.1s

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [January 31, 2019, 1:07pm UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/2 "2019-01-31T13:07:08Z")

</div>

You’ll need to use PackageCompiler!  
It automatically snoops your package from the runtests.jl (note that it isn’t using SnoopCompile anymore, since the functionality basically moved into base julia).  
The important step is, that it compiles a new system image that caches your ahead of time compiled code!  
i recommend using the new, compile\_incremental function!

_edit_ i think i didnt read your question carefully enough, so it’s a bit besides the topic, but i think it’s still worth looking into packagecompiler!

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [January 31, 2019, 1:38pm UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/3 "2019-01-31T13:38:39Z")

</div>

Thanks, I think PackageCompiler is super promising but a bit overkill for me at this point (though I will have another look at it).

I’m mostly surprised that warming up by calling stuff _in_ the module has practically no effect to calls _out_ of it; I would have expected the compiled stuff to be available globally & to not have to be recompiled yet again (which, based on timings, seems to be partially the case).  
Of course I’m probably phrasing/seeing this wrong as I know pretty much nothing about the compiler in Julia.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [January 31, 2019, 2:09pm UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/4 "2019-01-31T14:09:27Z")

</div>

Yeah I realized your question is more complicated - but because of that you actually need to give more data for us to say anything meaningful 😉  
Maybe make an minimal working example?

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [February 1, 2019, 1:36am UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/5 "2019-02-01T01:36:54Z")

</div>

Yes I figured someone might tell me off for not putting an MWE, I wasn’t sure I’d be able to reproduce the observation with something minimal but actually I was 🙂 Here’s a example (PS: the example is only meant to require specialisation and show something, not to be good code…)

file `Blah.jl`

```julia
module Blah

using LinearAlgebra

export Foo, foo

struct Foo{A<:Real, B<:Real, C<:Real}
    a::Vector{A}
    b::Vector{B}
    c::Vector{C}
end

bar(v::Vector{<:Real}) = maximum(v) - minimum(v) + norm(v)

foo(f::Foo) = bar(f.a) + bar(f.b) + bar(f.c)

function warmup()
    a = rand(Float16, 2)
    b = rand(Float32, 2)
    c = randn(2)
    foo(Foo(a, b, c))
end

warmup()

end # module

```

file `load.jl`

```julia
using Blah

a = rand(Float16, 100)
b = rand(Float32, 100)
c = randn(100)

@show @elapsed begin
    f = Foo(a, b, c)
    foo(f)
end

@show @elapsed begin
    f = Foo(a, b, c)
    foo(f)
end

```

Results commenting out `warmup()`:

```julia
0.557871823 # first call
1.805e-5 # second call

```

results with `warmup()` (in a fresh session)

```julia
0.547161082 # first call
1.6461e-5 # second call

```

I would have expected the first call, with the warmup, to have been much faster given that it’s pretty much exactly the same call (apart from dimensions).

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [February 1, 2019, 9:54am UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/6 "2019-02-01T09:54:00Z")

</div>

Note that modules are precompiled by default. So for module `Blah`, `warmup()` is only run when it is compiled. It will not run when `using Blah`. To see this, insert a print statement in `warmup()`.

To have `warmup()` run whenever `Blah` is first loaded, put `warmup()` in ` __init__ ()`

```julia
function warmup()
    println("warmup")
    a = rand(Float16, 2)
    b = rand(Float32, 2)
    c = randn(2)
    foo(Foo(a, b, c))
end

function __init__ ()
    warmup()
end

```

[https://docs.julialang.org/en/v1/manual/modules/index.html#Module-initialization-and-precompilation-1](https://docs.julialang.org/en/v1/manual/modules/index.html#Module-initialization-and-precompilation-1)

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [February 1, 2019, 12:08pm UTC](https://discourse.julialang.org/t/package-warmup-snoopcompile/20266/7 "2019-02-01T12:08:07Z")

</div>

Awesome that makes perfect sense and I was not aware of the **init** thank you!
