-
Notifications
You must be signed in to change notification settings - Fork 181
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reduce the time-to-first-request by adding pregenerated precompile st…
…atements
- Loading branch information
1 parent
96a0b34
commit d9b68be
Showing
3 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
function gen_single_tracefile( | ||
code::AbstractString, | ||
tracefile::AbstractString, | ||
) | ||
julia_binary = Base.julia_cmd().exec[1] | ||
cmd = `$(julia_binary)` | ||
push!(cmd.exec, "--compile=all") | ||
push!(cmd.exec, "--trace-compile=$(tracefile)") | ||
push!(cmd.exec, "-e $(code)") | ||
splitter = Sys.iswindows() ? ';' : ':' | ||
project = Base.active_project() | ||
env2 = copy(ENV) | ||
env2["JULIA_LOAD_PATH"] = "$(project)$(splitter)@stdlib" | ||
env2["JULIA_PROJECT"] = "$(project)" | ||
run(setenv(cmd, env2)) | ||
return nothing | ||
end | ||
|
||
function gen_single_precompile(code::AbstractString) | ||
str = mktempdir() do dir | ||
tracefile = joinpath(dir, "tracefile") | ||
gen_single_tracefile(code, tracefile) | ||
return read(tracefile, String)::String | ||
end::String | ||
lines = convert( | ||
Vector{String}, | ||
strip.(split(strip(str), '\n')), | ||
)::Vector{String} | ||
filter!(line -> !isempty(line), lines) | ||
return lines | ||
end | ||
|
||
function gen_all_precompile() | ||
codes = String[ | ||
"import HTTP; HTTP.get(\"https://example.com/\")", | ||
] | ||
all_lines = String[] | ||
for code in codes | ||
lines = gen_single_precompile(code) | ||
append!(all_lines, lines) | ||
end | ||
unique!(all_lines) | ||
end | ||
|
||
function write_all_precompile(io::IO, all_lines::Vector{String}) | ||
preamble_lines = String[ | ||
"import MbedTLS", | ||
"const MbedTLS_jll = MbedTLS.MbedTLS_jll" | ||
] | ||
for line in preamble_lines | ||
println(io, line) | ||
end | ||
println(io) | ||
println(io, """ | ||
function _precompile() | ||
""") | ||
println(io, """ | ||
if ccall(:jl_generating_output, Cint, ()) != 1 | ||
return nothing | ||
end | ||
""") | ||
println(io, """ | ||
@static if Base.VERSION < v"1.9-" | ||
# We need https://github.com/JuliaLang/julia/pull/43990, otherwise this isn't worth doing. | ||
return nothing | ||
end | ||
""") | ||
for line in all_lines | ||
println(io, " ", line) | ||
end | ||
println(io) | ||
println(io, """ | ||
return nothing | ||
end | ||
""") | ||
return nothing | ||
end | ||
|
||
function write_all_precompile( | ||
output_file::AbstractString, | ||
all_lines::Vector{String}, | ||
) | ||
open(output_file, "w") do io | ||
write_all_precompile(io, all_lines) | ||
end | ||
return nothing | ||
end | ||
|
||
function main() | ||
output_file = joinpath(dirname(@__DIR__), "src", "precompile.jl") | ||
all_lines = gen_all_precompile() | ||
write_all_precompile(output_file, all_lines) | ||
return nothing | ||
end | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import MbedTLS | ||
const MbedTLS_jll = MbedTLS.MbedTLS_jll | ||
|
||
function _precompile() | ||
|
||
if ccall(:jl_generating_output, Cint, ()) != 1 | ||
return nothing | ||
end | ||
|
||
@static if Base.VERSION < v"1.9-" | ||
# We need https://github.com/JuliaLang/julia/pull/43990, otherwise this isn't worth doing. | ||
return nothing | ||
end | ||
|
||
precompile(Tuple{typeof(Base.:(!=)), UInt64, UInt64}) | ||
precompile(Tuple{typeof(MbedTLS_jll.__init__)}) | ||
precompile(Tuple{typeof(MbedTLS.f_send), Ptr{Nothing}, Ptr{UInt8}, UInt64}) | ||
precompile(Tuple{typeof(MbedTLS.f_recv), Ptr{Nothing}, Ptr{UInt8}, UInt64}) | ||
precompile(Tuple{typeof(MbedTLS.__init__)}) | ||
precompile(Tuple{typeof(URIs.__init__)}) | ||
precompile(Tuple{typeof(HTTP.Parsers.__init__)}) | ||
precompile(Tuple{typeof(HTTP.CookieRequest.__init__)}) | ||
precompile(Tuple{typeof(HTTP.ConnectionRequest.__init__)}) | ||
precompile(Tuple{typeof(HTTP.Servers.__init__)}) | ||
precompile(Tuple{typeof(HTTP.MultiPartParsing.__init__)}) | ||
precompile(Tuple{typeof(HTTP.get), String}) | ||
precompile(Tuple{Type{NamedTuple{(:init,), T} where T<:Tuple}, Tuple{DataType}}) | ||
precompile(Tuple{Base.var"#reduce##kw", NamedTuple{(:init,), Tuple{DataType}}, typeof(Base.reduce), Function, Base.Set{Tuple{Union{Type{Union{}}, UnionAll}, UnionAll}}}) | ||
precompile(Tuple{typeof(Base.mapfoldl_impl), typeof(Base.identity), HTTP.var"#24#25", Type, Base.Set{Tuple{Union{Type{Union{}}, UnionAll}, UnionAll}}}) | ||
precompile(Tuple{typeof(HTTP.request), Type{HTTP.TopRequest.TopLayer{HTTP.RedirectRequest.RedirectLayer{HTTP.BasicAuthRequest.BasicAuthLayer{HTTP.MessageRequest.MessageLayer{HTTP.RetryRequest.RetryLayer{HTTP.ExceptionRequest.ExceptionLayer{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}}}}}}}, String, URIs.URI, Array{Pair{Base.SubString{String}, Base.SubString{String}}, 1}, Array{UInt8, 1}}) | ||
precompile(Tuple{HTTP.var"#request##kw", NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}, typeof(HTTP.request), Type{HTTP.ExceptionRequest.ExceptionLayer{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}}, URIs.URI, HTTP.Messages.Request, Array{UInt8, 1}}) | ||
precompile(Tuple{HTTP.var"#request##kw", NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}, typeof(HTTP.request), Type{HTTP.ConnectionRequest.ConnectionPoolLayer{HTTP.StreamRequest.StreamLayer{Union{}}}}, URIs.URI, HTTP.Messages.Request, Array{UInt8, 1}}) | ||
precompile(Tuple{typeof(Sockets.uv_getaddrinfocb), Ptr{Nothing}, Int32, Ptr{Nothing}}) | ||
precompile(Tuple{HTTP.ConnectionPool.var"#newconnection##kw", NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}, typeof(HTTP.ConnectionPool.newconnection), Type{MbedTLS.SSLContext}, Base.SubString{String}, Base.SubString{String}}) | ||
precompile(Tuple{typeof(Sockets.uv_connectcb), Ptr{Nothing}, Int32}) | ||
precompile(Tuple{typeof(Sockets.connect), Sockets.IPv4, UInt64}) | ||
precompile(Tuple{typeof(Base.setproperty!), Sockets.TCPSocket, Symbol, Int64}) | ||
precompile(Tuple{typeof(Base.notify), Base.GenericCondition{Base.Threads.SpinLock}}) | ||
precompile(Tuple{typeof(MbedTLS.f_rng), MbedTLS.CtrDrbg, Ptr{UInt8}, UInt64}) | ||
precompile(Tuple{typeof(Base.isopen), Sockets.TCPSocket}) | ||
precompile(Tuple{typeof(Base.getproperty), Sockets.TCPSocket, Symbol}) | ||
precompile(Tuple{typeof(Base.unsafe_write), Sockets.TCPSocket, Ptr{UInt8}, UInt64}) | ||
precompile(Tuple{typeof(Base.bytesavailable), Sockets.TCPSocket}) | ||
precompile(Tuple{typeof(Base.eof), Sockets.TCPSocket}) | ||
precompile(Tuple{typeof(Base.alloc_buf_hook), Sockets.TCPSocket, UInt64}) | ||
precompile(Tuple{Base.var"#readcb_specialized#671", Sockets.TCPSocket, Int64, UInt64}) | ||
precompile(Tuple{typeof(Base.min), UInt64, Int64}) | ||
precompile(Tuple{typeof(Base.unsafe_read), Sockets.TCPSocket, Ptr{UInt8}, UInt64}) | ||
precompile(Tuple{Type{Int32}, UInt64}) | ||
precompile(Tuple{typeof(HTTP.Messages.hasheader), HTTP.Messages.Request, String}) | ||
precompile(Tuple{typeof(HTTP.Messages.ischunked), HTTP.Messages.Request}) | ||
precompile(Tuple{typeof(HTTP.Messages.writeheaders), Base.GenericIOBuffer{Array{UInt8, 1}}, HTTP.Messages.Request}) | ||
precompile(Tuple{typeof(Base.unsafe_write), MbedTLS.SSLContext, Ptr{UInt8}, UInt64}) | ||
precompile(Tuple{typeof(Base.check_open), Sockets.TCPSocket}) | ||
precompile(Tuple{MbedTLS.var"#25#26"{MbedTLS.SSLContext}}) | ||
precompile(Tuple{typeof(Base.eof), MbedTLS.SSLContext}) | ||
precompile(Tuple{HTTP.StreamRequest.var"#2#3"{HTTP.ConnectionPool.Connection, HTTP.Messages.Request, Array{UInt8, 1}, HTTP.Streams.Stream{HTTP.Messages.Response, HTTP.ConnectionPool.Connection}}}) | ||
precompile(Tuple{typeof(Base.bytesavailable), MbedTLS.SSLContext}) | ||
precompile(Tuple{typeof(Base.unsafe_read), MbedTLS.SSLContext, Ptr{UInt8}, Int64}) | ||
precompile(Tuple{typeof(Base.readuntil), Base.GenericIOBuffer{Array{UInt8, 1}}, typeof(HTTP.Parsers.find_end_of_header)}) | ||
precompile(Tuple{typeof(Base.release), HTTP.ConnectionPool.ConnectionPools.Pool{HTTP.ConnectionPool.Connection}, Tuple{DataType, String, String, Bool, Bool}, HTTP.ConnectionPool.Connection}) | ||
precompile(Tuple{typeof(Base.isequal), Tuple{DataType, String, String, Bool, Bool}, Tuple{DataType, Base.SubString{String}, Base.SubString{String}, Bool, Bool}}) | ||
precompile(Tuple{typeof(Base.isopen), MbedTLS.SSLContext}) | ||
precompile(Tuple{MbedTLS.var"#21#23"{MbedTLS.SSLContext}, MbedTLS.SSLContext}) | ||
precompile(Tuple{MbedTLS.var"#15#16", MbedTLS.CRT}) | ||
precompile(Tuple{MbedTLS.var"#10#11", MbedTLS.CtrDrbg}) | ||
precompile(Tuple{MbedTLS.var"#8#9", MbedTLS.Entropy}) | ||
precompile(Tuple{MbedTLS.var"#17#19", MbedTLS.SSLConfig}) | ||
precompile(Tuple{typeof(Base.uvfinalize), Sockets.TCPSocket}) | ||
|
||
return nothing | ||
end | ||
|