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

deno_tcp latency is worse than node_tcp #2700

Closed
ry opened this issue Jul 31, 2019 · 9 comments
Closed

deno_tcp latency is worse than node_tcp #2700

ry opened this issue Jul 31, 2019 · 9 comments

Comments

@ry
Copy link
Member

ry commented Jul 31, 2019

Screen Shot 2019-07-31 at 8 09 21 AM

Thanks to @bartlomieju's work in #2689 we're able to clearly see now that deno_tcp has worse 99% tail latency than node_tcp.

Previously I believed that our max latency was on par with Node's. Back in April, @piscisaureus did work to improve our latency numbers, but apparently it was not enough.

This is a very good place to investigate performance problems.

Note that deno_core_single does not exhibit the latency problems! deno_core_multi is worse, but not as bad as deno_tcp....

@bartlomieju
Copy link
Member

Ref #2758

@bartlomieju
Copy link
Member

Interestingly deno_http has 4x lower latency than deno_tcp!

Zrzut ekranu 2019-08-19 o 16 14 22

@lucacasonato
Copy link
Member

lucacasonato commented Aug 13, 2020

Can this be closed? deno_tcp averages at about the same latency, or slightly better than node_tcp now. https://deno.land/benchmarks?-50#http-latency

@ry
Copy link
Member Author

ry commented Aug 13, 2020

Yes - this is fixed.

@ry ry closed this as completed Aug 13, 2020
@hayd
Copy link
Contributor

hayd commented Apr 4, 2021

there appears to be a relatively recent (?) regression:

Screen Shot 2021-04-04 at 20 59 00

https://deno.land/benchmarks?-100#http-latency

@AaronO
Copy link
Contributor

AaronO commented Apr 4, 2021

This divergence seems to have started with fec1b2a (first commit changing the OP layer)

So this is on my radar, but it's curious that there's a big regression in latency. I'll try to investigate this and correct it for 1.9 (and ideally exceed the original latency)

@lucacasonato lucacasonato reopened this Apr 4, 2021
@AaronO
Copy link
Contributor

AaronO commented Apr 5, 2021

@hayd I believe I've identified why performance & latency regressed with fec1b2a.

TLDR: serde_json::Values are very inefficient with serde_v8 (take all slow paths)

Ultimately it's a combination of a few factors that should not be present in 1.9:

  • rumtime/tcp ops still use serde_json-isms and take/return serde_json::Values
  • These are loosely-typed maps, which take serde_v8's slowpaths
    • Can't use v8_struct_key so each field allocates a new v8 string on heap (will cause GC pressure)
    • This happens both for input args and output returns
    • Each key has to go through v8's string write utf8 which converts the strings
  • Serializing/deserializing Maps hasn't been optimized at all in serde_v8 and in fact has no benches (yet)
    • In fact there's a known inefficiency in deserialize_map (which doubles v8::Object::Get calls), added to drop keys that exists but whose values are undefined which is what serde_json did and is behaviour that we relied on, at least in tests
  • Plus the overhead of allocating the unnecessary serde_json::Value

So removing these serde_json-isms like I've done in #10009 should fix the regression and likely deliver better performance.

@AaronO
Copy link
Contributor

AaronO commented Apr 5, 2021

After further digging, the P99 latency increase appears to be caused by the promiseTable change.

#9843 changed the promiseTable from a JS Object to a Map, which causes higher GC-pressure and thus higher tail latencies.

Checking out the promise ring (#9979), hugely closed the P99 delta between node and deno on the tcp bench

@AaronO
Copy link
Contributor

AaronO commented Apr 18, 2021

@ry @hayd I would consider this closed with the op improvements that shipped in 1.9.0, deno_tcp has lower max latency than node_tcp (I still think we should use P99 or something instead of max, max isn't a meaningful statistical measurement and can be caused by a single outlier) current chart:

image

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

No branches or pull requests

5 participants