c-cube / tiny_httpd

Minimal HTTP server using good old threads + blocking IO, with a small request router.
https://c-cube.github.io/tiny_httpd
75 stars 11 forks source link

Small file should not be chunked #54

Closed craff closed 1 year ago

craff commented 1 year ago

When using Tiny_httpd_dir, all files are chunked and needs at least 2 write. It would be easy to get the file size (there is already a call to Unix.stat to get mtime) and use String instead ofStream for small enough file.

c-cube commented 1 year ago

Good point. If we already stat it should be fairly easy to then read that many bytes in one go, in bytes, and turn that to a string.

craff commented 1 year ago

I did some testing... Probably not worth it. The important point is not to flush in the loop for chunked_output. I will submit a PR with just a comment maybe. This way, the final five bits are in the same message as the end of the previous chunk and, for small file, we get only one or two transfer unit.

With wrk (I think wrk suffer from a bug ?) a flush at each loop can decrease the perf by a factor 40!

c-cube commented 1 year ago

We found the cause for that btw: Naggle! With TCP_NODELAY it's not a problem anymore. There's no x40 penalty.

craff commented 1 year ago

Simon Cruanes @.***> writes:

We found the cause for that btw: Naggle! With TCP_NODELAY it's not a problem anymore. There's no x40 penalty.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.

Probably cork true while writing the response, cork false at flush should even be better.

But cork is linux only...

-- Christophe Raffalli tél: +689 87 23 11 48 web: http://raffalli.eu my mails should pass DKIM/SPF tests/mes messages doivent passer les tests DKIM/SPF

vphantom commented 1 year ago

TCP_NODELAY specifically disables Nagle's algorithm because it is detrimental to HTTP connections, which aren't very interactive. In HTTP (1.x anyway), the client sends its full request and then listens silently while the server sends its response. There is thus no benefit to have the client delay some of its ACKs (40ms in current implementations) in case it has something to send, because it never will.

Conversely, TCP_CORK is undesirable for Tiny_httpd specifically, because write operations are already bundled enough: headers are generated in one go for instance, and are not handed to the kernel individually. They are even already sent to the kernel along with a first chunk of content AFAIK. Corking responses would effectively delay "time to first byte" (by 200ms in current implementations) along with the browser's opportunity to perform some optimizations based on headers received and possibly the HTML <head/> (such as loading CSS/JS resources in parallel). This is especially true with the new Writer I/O scheme in 0.14 which allows us to potentially send headers and <head/>, flush, and then send the body.