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

Increasing read chunk size could improve performance for large responses #135

Closed
florimondmanca opened this issue Aug 5, 2020 · 2 comments · Fixed by #136
Closed

Increasing read chunk size could improve performance for large responses #135

florimondmanca opened this issue Aug 5, 2020 · 2 comments · Fixed by #136

Comments

@florimondmanca
Copy link
Member

florimondmanca commented Aug 5, 2020

Coming from discussion on Gitter with @dalf

Currently we are reading response data in chunks of 4kB…

READ_NUM_BYTES = 4096

READ_NUM_BYTES = 4096

Benchmarking using @dalf's pyhttp-benchmark tool led us to see that increasing this number to 64kB could lead 2-3x execution time improvement for large responses (typically > 256kB).

My rationale would be that reading N bytes in one go via a syscall is faster than reading n = N/k bytes k times — mostly because the kernel is way faster than Python.

@florimondmanca
Copy link
Member Author

florimondmanca commented Aug 5, 2020

Running the 1MB-response benchmark for various READ_NUM_BYTES values, and a matplotlib script later, here's a handy little plot to support this assessment that 64kB is probably a good value…

import matplotlib.pyplot as plt

data = [
    (4, 2.36, 2.13),
    (16, 1.18, 0.99),
    (32, 1.07, 0.94),
    (64, 0.95, 0.81),
    (96, 0.87, 0.74),
    (128, 0.82, 0.68),
    (160, 0.80, 0.66),
]

x, runtime, cpu = zip(*data)

plt.grid()
plt.xlabel("READ_NUM_BYTES (kB)")
plt.xticks(range(0, 192, 16))
plt.ylim(0, 3)
plt.ylabel("Median execution time (s)")
plt.scatter(x, runtime)
plt.scatter(x, cpu)
plt.legend(["runtime", "cpu"])
plt.show()

plot

Looks like the median execution time gets exponentially smaller as we increase the chunk size. Once we hit 32kB the marginal improvement starts hitting its limits. 64kB gets us "below 1s in wall time for a 1MB response" and that sounds very satisfying. :-)

@dalf
Copy link

dalf commented Aug 5, 2020

An additional graph (made using this tool):
image

  • httpcore_True_*: http2=True
  • httpcore_False_* : http2=False

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 a pull request may close this issue.

2 participants