Skip to content

Add minor precompile workload#750

Closed
rikhuijzer wants to merge 3 commits into
JuliaWeb:masterfrom
rikhuijzer:precompile
Closed

Add minor precompile workload#750
rikhuijzer wants to merge 3 commits into
JuliaWeb:masterfrom
rikhuijzer:precompile

Conversation

@rikhuijzer
Copy link
Copy Markdown
Contributor

@rikhuijzer rikhuijzer commented Sep 5, 2021

Just like my attempt in #738, I'm on a mission to reduce the time to first HTTP.get. Precompile a bigger part of the workload seems like low hanging fruit compared to the rewrite in that PR.

As a proof-of-concept, I've only added HTTP.get for now.

Demo

I've run @time using HTTP; @time HTTP.get("http://example.com") twice on master and precompile with Julia 1.7-beta3.0:

rik@nixos ~/g/HTTP.jl (master)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  2.374460 seconds (1.87 M allocations: 102.031 MiB, 0.87% gc time, 1.02% compilation time)
  3.711768 seconds (7.92 M allocations: 418.646 MiB, 6.11% gc time)

rik@nixos ~/g/HTTP.jl (precompile)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  4.184486 seconds (1.99 M allocations: 109.878 MiB, 0.51% gc time, 0.58% compilation time)
  3.053110 seconds (4.49 M allocations: 239.125 MiB, 1.89% gc time)

rik@nixos ~/g/HTTP.jl (master)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  2.416790 seconds (1.87 M allocations: 102.046 MiB, 0.88% gc time, 1.02% compilation time)
  3.486002 seconds (7.92 M allocations: 418.657 MiB, 4.36% gc time)

rik@nixos ~/g/HTTP.jl (precompile)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  4.140951 seconds (1.99 M allocations: 109.938 MiB, 0.48% gc time, 0.59% compilation time)
  3.161522 seconds (4.49 M allocations: 239.152 MiB, 1.82% gc time)

As you can see, precompilation takes 2 seconds longer on precompile. However, the first HTTP.get is sped up by 0.3-0.7 seconds (allocations are reduced by 180 MiB).

@timholy, could you take a quick look to see whether I've implemented it correctly?

@rikhuijzer
Copy link
Copy Markdown
Contributor Author

I don't know why the tests fail. The tests pass locally on Julia 1.6.1 and Julia 1.7-beta3.0.

Comment thread src/precompile.jl
@rikhuijzer
Copy link
Copy Markdown
Contributor Author

rikhuijzer commented Sep 8, 2021

Updated demo

With Julia 1.6.2:

rik@nixos ~/g/HTTP.jl (master)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  2.603166 seconds (2.05 M allocations: 121.065 MiB, 1.15% gc time, 22.43% compilation time)
  3.317185 seconds (7.53 M allocations: 431.373 MiB, 6.20% gc time, 1.45% compilation time)

rik@nixos ~/g/HTTP.jl (master)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
  0.537877 seconds (606.13 k allocations: 36.799 MiB)
  3.214055 seconds (7.53 M allocations: 431.381 MiB, 5.26% gc time, 1.42% compilation time)



rik@nixos ~/g/HTTP.jl (precompile)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  4.123068 seconds (2.16 M allocations: 128.386 MiB, 0.55% gc time, 13.66% compilation time)
  2.650265 seconds (4.22 M allocations: 244.392 MiB, 2.28% gc time, 95.24% compilation time)

rik@nixos ~/g/HTTP.jl (precompile)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
  0.604902 seconds (715.10 k allocations: 44.111 MiB, 1.62% gc time)
  2.792045 seconds (4.22 M allocations: 244.404 MiB, 1.58% gc time, 91.93% compilation time)



rik@nixos ~/g/HTTP.jl (master)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  2.612097 seconds (2.05 M allocations: 121.121 MiB, 1.18% gc time, 24.54% compilation time)
  3.233083 seconds (7.53 M allocations: 431.332 MiB, 5.80% gc time, 1.39% compilation time)

rik@nixos ~/g/HTTP.jl (master)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
  0.559991 seconds (606.08 k allocations: 36.856 MiB)
  3.239811 seconds (7.53 M allocations: 431.340 MiB, 4.34% gc time, 1.46% compilation time)



rik@nixos ~/g/HTTP.jl (precompile)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
[ Info: Precompiling HTTP [cd3eb016-35fb-5094-929b-558a96fad6f3]
  4.284226 seconds (2.16 M allocations: 128.239 MiB, 0.66% gc time, 13.38% compilation time)
  2.751134 seconds (4.22 M allocations: 244.407 MiB, 1.93% gc time, 95.25% compilation time)

rik@nixos ~/g/HTTP.jl (precompile)> julia --project -ie '@time using HTTP; @time HTTP.get("http://example.com")'
  0.609435 seconds (712.96 k allocations: 43.971 MiB, 1.55% gc time)
  2.675962 seconds (4.22 M allocations: 244.419 MiB, 2.00% gc time, 95.28% compilation time)

So, this gives the following means and means differences over two runs:

Stage master-branch time (allocations) precompile-branch time (allocations) difference time (allocations)
using HTTP.jl with precompilation (2 datapoints) 2.6 seconds (2.05 MiB) 4.2 seconds (2.16 MiB) +62% (+5%)
using HTTP.jl (2 datapoints) 0.54 seconds (36.75 MiB) 0.6 seconds (43.5 MiB) +11% (+19%)
HTTP.get (4 datapoints) 3.2 seconds (431 MiB) 2.7 seconds (244 MiB) -15% (-43%)

EDIT: I leave it up to you to decide whether this tradeoff is worth it. I think that saving about 0.5 seconds per use is worth it, but I might be biased.

@rikhuijzer
Copy link
Copy Markdown
Contributor Author

rikhuijzer commented Sep 8, 2021

Is it possible that the tests fail due to a missing API key? In one of the test failures, I see "{\"error\":\"Missing apiKey\"}". Locally, the tests pass.

@quinnj
Copy link
Copy Markdown
Member

quinnj commented Sep 8, 2021

Is it possible that the tests fail due to a missing API key? In one of the test failures, I see "{\"error\":\"Missing apiKey\"}". Locally, the tests pass.

Yes, it's a current known issue for PRs coming from forks.

@fredrikekre
Copy link
Copy Markdown
Member

Personally I think it is a bit strange that HTTP.jl would do a HTTP request during precompilation. What if there is a server listening on this port?

Isn't this simple enough to handle via PackageCompiler?

@timholy
Copy link
Copy Markdown
Contributor

timholy commented Sep 26, 2021

PackageCompiler should be our past, not our future 😄. The future should be nice compiled code cached with each package, each upgradable independently.

@rikhuijzer
Copy link
Copy Markdown
Contributor Author

Yes, I'm aware that the implementation isn't perfect yet and am definitely open to better ideas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants