Closed craff closed 1 year ago
Tests using wrk againt http_of_dir. Without the PR a lot of errors:
raffalli@oulala:~/Programming/tiny_httpd$ wrk -t5 -c100 -d1 http://localhost:8080/echo.sh
Running 1s test @ http://localhost:8080/echo.sh
5 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.90ms 1.78ms 36.26ms 87.99%
Req/Sec 4.23k 2.15k 10.04k 57.14%
17692 requests in 1.10s, 2.25MB read
Non-2xx or 3xx responses: 17622 <----- ERRORS
With the PR, no error
raffalli@oulala:~/Programming/tiny_httpd$ wrk -t5 -c100 -d1 http://localhost:8080/echo.sh
Running 1s test @ http://localhost:8080/echo.sh
5 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 39.40ms 27.80ms 224.91ms 75.11%
Req/Sec 522.94 288.25 2.31k 94.12%
2657 requests in 1.10s, 541.99KB read
Requests/sec: 2407.38
Transfer/sec: 491.07KB
thank you. good fix.
The perf for simple_httpd using 5 domains + 1 for accept, on the same example are much better (reason below)
with 300 connections
raffalli@oulala:~/Programming/simple_httpd/_build/default/tests$ wrk -t5 -c300 -d10 --timeout 100 http://localhost:8081/echo.sh
Running 10s test @ http://localhost:8081/echo.sh
5 threads and 300 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 283.90ms 1.20s 10.00s 94.09%
Req/Sec 25.19k 14.75k 60.63k 78.83%
688851 requests in 10.04s, 124.16MB read
Requests/sec: 68605.82
Transfer/sec: 12.37MB
with 5 connection
`̀
raffalli@oulala:~/Programming/simple_httpd/_build/default/tests$ wrk -t5 -c5 -d10 --timeout 100 http://localhost:8081/echo.sh
Running 10s test @ http://localhost:8081/echo.sh
5 threads and 5 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 318.70us 1.26ms 20.94ms 95.18%
Req/Sec 14.46k 2.26k 19.25k 69.60%
720098 requests in 10.02s, 129.79MB read
Requests/sec: 71869.16
Transfer/sec: 12.95MB
Almost same speed ;-) and 30 faster than tiny_httpd. I think the gain is because I had to write by own output buffer for the scheduler to work on write too. I think this scheduler could benefit to Tiny_httpd.
not going to happen, since tiny_httpd will remain compatible with OCaml < 5.0.
My output buffer is not related to ocaml 5. It is just a replacement for the out_channel of OCaml. But I am not sure it is the only reason for speed. I did one optimisation for large file/string:
I am not sure OCaml does this. Here is the code, if it interest you, I could backport it to Tiny_httpd (if it is indeed faster):
module Out_buf = struct
type t = { fd : Simple_httpd_domain.client; b: Bytes.t
; mutable o : int; s : int }
let create ?(buf_size=16* 4_096) fd =
{fd; s=buf_size; o = 0; b=Bytes.make buf_size ' '}
let push oc =
assert(oc.o = oc.s);
let w = Simple_httpd_domain.write oc.fd oc.b 0 oc.s in
if w < oc.s then
begin
Bytes.blit oc.b oc.o oc.b 0 (oc.s - w);
oc.o <- oc.s - w
end
else
oc.o <- 0
let flush oc =
let n = ref 0 in
while !n < oc.o do
let w = Simple_httpd_domain.write oc.fd oc.b !n (oc.o - !n) in
n := !n + w
done;
oc.o <- 0
let close oc =
flush oc; Simple_httpd_domain.close oc.fd
let add_substring oc str offset len =
if oc.o + len < oc.s then
begin
Bytes.blit_string str offset oc.b oc.o len;
oc.o <- oc.o + len
end
else
begin
let start =
if oc.o > 0 then
begin
let nb = oc.s - oc.o in
Bytes.blit_string str offset oc.b oc.o nb;
oc.o <- oc.s;
flush oc;
offset + nb
end
else
offset
in
let n = ref start in
while len - !n >= oc.s do
let str = Bytes.unsafe_of_string str in
let w = Simple_httpd_domain.write oc.fd str !n (len - !n) in
n := !n + w
done;
Bytes.blit_string str !n oc.b 0 (len - !n);
oc.o <- len - !n
end
let add_string oc str = add_substring oc str 0 (String.length str)
let printf oc format =
let cont s = add_string oc s in
Printf.ksprintf cont format
let add_bytes oc str =
add_string oc (Bytes.unsafe_to_string str)
let add_subbytes oc str offset len =
add_substring oc (Bytes.unsafe_to_string str) offset len
let add_char oc c =
if oc.o >= oc.s then push oc;
Bytes.set oc.b oc.o c;
oc.o <- oc.o + 1
end
The Simple_httpd_domain.write should be replaced by Unix.write (or Unix.single_write)
I will also check what out_channel do ... I could propose a PR to ocaml too ?
output_string of OCaml is in C !
I did some check ... My proposed buffer are as fast as ocaml out_channel, but not faster. So no need to do anything.
I submit a PR for issue #52