Skip to content

Base.precompile is highly effective - can it be auto-inserted? Documented? #12897

@IainNZ

Description

@IainNZ

This is a very contrived reduced example to demonstrate my point, but I see the same effect in real JuMP and JuMPeR code.

Basically, Base.precompile is capable of slashing first-run times for functions by factors of 2 to 4 in my tests. For users at the REPL, or even just running small scripts, this has greatly improved the user experience. Getting a simple example is tricky, but considering the following code. Right at the bottom is a commented out call to Base.precompile.

Here is my test script:

tic()
using PrecompTest
toc()
@time PrecompTest.complicated(10,1.0,2.0,3.0,4.0,5.0)
@time PrecompTest.complicated(10,1.0,2.0,3.0,4.0,5.0)
@time PrecompTest.complicated(10,1.0,2.0,3.0,4.0,5.0)

Without Base.precompile

elapsed time: 0.27908636 seconds
  0.168520 seconds (337.81 k allocations: 15.117 MB, 11.94% gc time)
  0.000021 seconds (5 allocations: 176 bytes)
  0.000021 seconds (5 allocations: 176 bytes)

With Base.precompile

elapsed time: 0.267551923 seconds
  0.054533 seconds (6.53 k allocations: 331.406 KB)
  0.000023 seconds (5 allocations: 176 bytes)
  0.000025 seconds (5 allocations: 176 bytes)

With is 3x speed up for the first run.

In this case, because all the arguments are specified, it would actually be possible to auto-generate that Base.precompile call. My first question/idea would be to auto-generate that call if the package is precompiled. Second, is documenting this (and the other great compile speed up trick, avoiding kwargs) desirable? I could see an argument for it not being a great idea to document due to how deep it gets into the internals and is something that can and hopefully will change over time.

Here is the (contrived example) test module, PrecompTest.jl:

__precompile__()

module PrecompTest

    function complicated(N::Int, foo::Float64, bar::Float64, fizz::Float64, buzz::Float64, yo::Float64)
        data_so_far = foo + bar + fizz + buzz + yo
        for i in 1:N
            data_so_far += sqrt(cos(sin(data_so_far))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        temp1 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp1 += sqrt(cos(sin(temp1))^2)
        end
        temp2 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp2 += sqrt(cos(sin(temp2))^2)
        end
        temp3 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp3 += sqrt(cos(sin(temp3))^2)
        end
        temp4 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp4 += sqrt(cos(sin(temp4))^2)
        end
        temp5 = foo + bar + fizz + buzz + yo
        for i in 1:N
            temp5 += sqrt(cos(sin(temp5))^2)
        end
        return data_so_far+temp1*temp2+temp3*temp4+temp5
    end
    #Base.precompile(complicated, (Int, Float64, Float64, Float64, Float64, Float64))
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:precompilationPrecompilation of modulesdocsThis change adds or pertains to documentationperformanceMust go faster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions