Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minor precompile workload #750

Closed
wants to merge 3 commits into from

Conversation

rikhuijzer
Copy link
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
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.

@rikhuijzer
Copy link
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
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
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
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
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
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