mpenet / hirundo

Helidon 4.x RING adapter - using loom/java21+
Eclipse Public License 2.0
100 stars 7 forks source link

Performance issue #27

Open valerauko opened 4 days ago

valerauko commented 4 days ago

Hey, I've been playing around a little and I noticed something weird. hirundo seems to be approx 1000 times slower than the jetty 12 adapter with otherwise identical (default) configs. I haven't been able to thoroughly profile it (yet) but this definitely doesn't feel right

[com.s-exp/hirundo "0.1.40"]

(defn -main
  [& _]
  (hirundo/start!
   {:http-handler (constantly {:status 200
                               :body "Hello, world!"})
    :port 8080}))

Hitting / with wrk then results in a consistent 45ms for a constant response.

$ wrk -c 4 -t 4 http://localhost:8080
Running 10s test @ http://localhost:8080
  4 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    45.35ms    3.53ms  48.28ms   99.55%
    Req/Sec    22.00      4.01    30.00     80.00%
  880 requests in 10.01s, 113.00KB read
Requests/sec:     87.94
Transfer/sec:     11.29KB

[info.sunng/ring-jetty9-adapter "0.36.0"]

By comparison the jetty 12 adapter is about 1k times faster.

(defn -main
  [& _]
  (jetty/run-jetty
   (constantly {:status 200
                :body "Hello, world!"})
   {:port 8080}))
$ wrk -c 4 -t 4 http://localhost:8080
Running 10s test @ http://localhost:8080
  4 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    52.06us  178.93us   9.14ms   98.80%
    Req/Sec    24.62k     2.82k   27.13k    97.03%
  989742 requests in 10.10s, 88.73MB read
Requests/sec:  97999.35
Transfer/sec:      8.79MB

Env: clojure:temurin-23-lein-noble container with clojure 1.12

mpenet commented 4 days ago

Thanks for the report!

I have the (gut) feeling the recently added ring StreamableResponseBody support could be a hotspot, the underlying ring code is not really optimized and since String body writing defaults to Object currently, it would hit that code path. This should be quite easy to fix (for simple string bodies). I will try to look into hit tomorrow.

With the early version of hirundo I managed to hit 100k req/s "on my laptop" (I know ... 😅 ) being in the same ballpark of most of what I could compare it with on the same machine. I am hoping we can get back to the same place at least.

mpenet commented 4 days ago

I threw in a simple patch based on this intuition, and now we hit 46k req/s

❯  wrk -c 4 -t 4 http://localhost:8080
Running 10s test @ http://localhost:8080
  4 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   144.07us    0.95ms  30.07ms   98.98%
    Req/Sec    11.79k   780.66    12.31k    98.27%
  473817 requests in 10.10s, 70.49MB read
Requests/sec:  46913.52
Transfer/sec:      6.98MB

It's still not where it should be (imo), but it's less embarrassing 😄 at least. Like I said, more to come.

Thanks again for the report!

mpenet commented 4 days ago

available as 0.1.41