-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
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