HTTP.jl icon indicating copy to clipboard operation
HTTP.jl copied to clipboard

Revisit src/precompile.jl

Open samoconnor opened this issue 6 years ago • 7 comments

src/precompile.jl is currently empty.

Maybe resist this to see if load times can be improved. Or, maybe not, if there is not much of a load-time issue anyway https://github.com/JuliaWeb/HTTP.jl/issues/147.

Having too many precompiled methods in the .ji file might actually slow down the load time.

@quinnj what do you think?

samoconnor avatar Feb 28 '18 04:02 samoconnor

I definitely think it's worth it. I also don't think they will affect load time significantly.

quinnj avatar Feb 28 '18 13:02 quinnj

I think this should probably be done at the same time: https://github.com/JuliaWeb/HTTP.jl/blob/20c454788f6099d32711abf652efdcc3fcaff66a/src/HTTP.jl#L289-L291

It would be good to avoid having an exponentially large set of specialised methods, and good to avoid large code size sue to unnecessarily aggressive inlining.

In places where we are unavoidably waiting for IO we can afford to do a little bit of dynamic dispatch. In places where we are reading a memory buffer through a stack of abstractions we want maximum inlining and optimisation. But, for example, we might want to avoid ending up with a huge inlined write method specialised for each type of thing that we're writing. It might be better to convert to a common type at the top of the stack.

I think the first step should be to come up with an example/benchmark script that uses the API in a variety of ways, but where the variety is intended to be as real-world as possible. e.g. we allow a fairly wide range of types for body= but we should think about which are the most used and target our tuning of @nospecialize and precompile towards that set.

It might also be worth looking into what the compiler does with the Stack{Next{Next{Next.... scheme. There is a trivial example in the doc showing how it can all be inlined, but it might be good to check if any inlining is actually being done for our default stack (and if not, does it matter?). https://github.com/JuliaWeb/HTTP.jl/blob/20c454788f6099d32711abf652efdcc3fcaff66a/src/HTTP.jl#L405-L412

samoconnor avatar Feb 28 '18 21:02 samoconnor

FWIW, I have found little benefit to precompile.jl unless one combines it with sysimg precompilation. Then the effect is immense.

KristofferC avatar Mar 09 '18 08:03 KristofferC

I guess we should make HTTP.jl a stdlib then ;)

quinnj avatar Mar 22 '18 04:03 quinnj

sadly PackageCompiler throws errors when HTTP.jl is included:

julia> using PackageCompiler

julia> build_executable("compile.jl")
Julia program file:
  "/Users/arthurb/investments/compile.jl"
C program file:
  "/Users/arthurb/.julia/packages/PackageCompiler/BBtC7/examples/program.c"
Build directory:
  "/Users/arthurb/investments/builddir"
fatal: error thrown and no exception handler available.
ErrorException("Task cannot be serialized")
rec_backtrace at /Users/osx/buildbot/slave/package_osx64/build/src/stackwalk.c:94
record_backtrace at /Users/osx/buildbot/slave/package_osx64/build/src/task.c:246 [inlined]
jl_throw at /Users/osx/buildbot/slave/package_osx64/build/src/task.c:577
jl_error at /Users/osx/buildbot/slave/package_osx64/build/src/rtutils.c:41
jl_serialize_value_ at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:293
jl_serialize_value_ at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:285
jl_serialize_module at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:229 [inlined]
jl_serialize_value_ at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:290
jl_serialize_module at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:229 [inlined]
jl_serialize_value_ at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:290
jl_serialize_module at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:221 [inlined]
jl_serialize_value_ at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:290
jl_save_system_image_to_stream at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:1272
jl_create_system_image at /Users/osx/buildbot/slave/package_osx64/build/src/staticdata.c:1377
jl_write_compiler_output at /Users/osx/buildbot/slave/package_osx64/build/src/precompile.c:68
jl_atexit_hook at /Users/osx/buildbot/slave/package_osx64/build/src/init.c:233
main at /Applications/Julia-0.7.app/Contents/Resources/julia/bin/julia (unknown line)
ERROR: failed process: Process(`/Applications/Julia-0.7.app/Contents/Resources/julia/bin/julia -Cnative -J/Applications/Julia-0.7.app/Contents/Resources/julia/lib/julia/sys.dylib --compile=yes --depwarn=yes --startup-file=no --compiled-modules=no --output-o compile.a -e 'Base.__init__(); Sys.__init__() # initialize \`Base\` and \`Sys\` modules
pushfirst!(Base.DEPOT_PATH, "cache_ji_v0.7.0") # save precompiled modules locally
include("/Users/arthurb/investments/compile.jl") # include Julia program file
'`, ProcessExited(1)) [1]
Stacktrace:
 [1] error(::String, ::Base.Process, ::String, ::Int64, ::String) at ./error.jl:42
 [2] pipeline_error at ./process.jl:712 [inlined]
 [3] #run#509(::Bool, ::Function, ::Cmd) at ./process.jl:670
 [4] run(::Cmd) at ./process.jl:668
 [5] (::getfield(PackageCompiler, Symbol("##4#5")))() at /Users/arthurb/.julia/packages/PackageCompiler/BBtC7/src/static_julia.jl:261
 [6] cd(::getfield(PackageCompiler, Symbol("##4#5")), ::String) at ./file.jl:96
 [7] build_object(::String, ::String, ::String, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing) at /Users/arthurb/.julia/packages/PackageCompiler/BBtC7/src/static_julia.jl:260
 [8] #static_julia#1(::Nothing, ::Bool, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Nothing, ::Bool, ::Bool, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::typeof(static_julia), ::String) at /Users/arthurb/.julia/packages/PackageCompiler/BBtC7/src/static_julia.jl:172
 [9] #static_julia at ./none:0 [inlined]
 [10] #build_executable#22 at /Users/arthurb/.julia/packages/PackageCompiler/BBtC7/src/api.jl:104 [inlined]
 [11] build_executable at /Users/arthurb/.julia/packages/PackageCompiler/BBtC7/src/api.jl:104 [inlined] (repeats 2 times)
 [12] top-level scope at none:0

my test script is

module TestCompile
 
using HTTP

Base.@ccallable function julia_main(ARGS::Vector{String})::Cint
  return 0
end

end

bjarthur avatar Nov 08 '18 12:11 bjarthur

i should add that the problem is not with its dependencies. both MbedTLS and IniFile compile fine.

bjarthur avatar Nov 08 '18 12:11 bjarthur

bump, currently looking at 99.8% compilation time when reading a file header via HTTP.jl GET

Moelf avatar Feb 23 '22 15:02 Moelf