ThePrimeagen / tyrone-biggums

Clearly a repo about websockets and their comparison...
Other
463 stars 56 forks source link

Alternate implementation for Rust #8

Closed devashishdxt closed 2 years ago

devashishdxt commented 2 years ago

I saw your video on YouTube and was surprised that the bullet game code written in Rust was not performing as good as (if not better than) Go. This made me curious and I went through the Rust code.

I've created an alternate implementation of the game in Rust which doesn't use any Mutex and very few channels. Hopefully this one should perform better than the current implementation.

To compile and run:

cd rust-alternate/
cargo build --release --bin server
./target/release/server start

If you want to change log level:

RUST_LOG=error ./target/release/server start

You can test this using the same game_player.rs in current code.

marc2332 commented 2 years ago

I also took a look at the code and I wonder if using async_trait in the Rust Socket might be causing any performance issue.

devashishdxt commented 2 years ago

@marc2332 async_trait will use dynamic dispatch which is slightly inefficient than static dispatch. But, in most use cases, that shouldn't be a problem. Also, async_trait, in my opinion, will not cause the spikes in performance drop that he's talking about in the YouTube video.

chanced commented 2 years ago

I was confused by the number of channels, especially wrt the timeout impl.

devashishdxt commented 2 years ago

I was confused by the number of channels, especially wrt the timeout impl.

Yeah. I have the same feeling. Current implementation over-uses Mutex and channel even for doing trivial things.

pro465 commented 2 years ago

that was the exact thing i was planning to do, but thanks for saving my time!

pro465 commented 2 years ago

i wonder why did he choose this complicated and inefficient route in the first place, and not keep it simple like his go version? maybe stuff like this was the reason why he took 5x more time to write it in rust than go?

ThePrimeagen commented 2 years ago

Howdy @pro465

I tried to keep the implementations is close as possible.

As I've said many times, it's really hard to write good rust. For you, it seems to be much easier. My assumptions you've been writing rust for at least a little while. I started writing rust in December, and just trying to use it the best I can. Still learning. Other languages do not have such learning curves as this language.

As far as this PR goes, on Monday, I'll be glad to take a review. I've already talked to Benny in the discord about this.

And I also wrote out while memeing in front of ~500 people ;)

pro465 commented 2 years ago

oh yeah that is fair then. i actually started in ~august when the corona gave me free time. i can imagine the pressure you had to endure while coding in front of 500 people, while also having not used to rust as much.

good luck in your rusty journey!

ThePrimeagen commented 2 years ago

Yaya! I am stoked to see this code to give the ol +1 to the skill set.

devashishdxt commented 2 years ago

Thanks. This implementation is still not as optimized as it can be. I've used HashMap at a few places where I can just use an array (which will avoid a few heap allocations). But, I think it is good enough for your benchmarks.

ThePrimeagen commented 2 years ago

I have intentionally not hyperoptimized the golang version either.

Part of this is simple writing of a program and how does it perform. They have almost identical algorithms. Now we have a divergent algorithm, which makes me want to upgrade the golang one to make it significantly better. I'm pretty sure I could 10x the performance on golang

benwis commented 2 years ago

@devashishdxt Thanks for writing this, you beat me to it. About how long did it take you to write? @ThePrimeagen Happy to see how this does against the Go one. I don't think it's hyperoptimized, but maybe you'd like to do a hyperoptimized video where he has people from each community submit their best effort and compare them. Talk about time spent on each language, optimizations, and algos.

ThePrimeagen commented 2 years ago

@benwis I think this is a great idea.

This can be the start of the optimization version. I am glad to give you merge permissions if you wish to spearhead the rust version. And by spearhead I mean approve or disapprove any of the changes.

ThePrimeagen commented 2 years ago

Also, I don't really believe in commenting code, but for this purpose, a learning adventure, I do think commenting would be very good.

Any further changes please consider commenting it

benwis commented 2 years ago

Happy to do it. And I agree comments here would be beneficial

chanced commented 2 years ago

@ThePrimeagen You really should give axum a try. Never mind the benchmarks, it's worth it just to experience development of a server with a higher level of abstraction in rust to get a real feel for it.

Go follows an incredibly conservative mantra to keep the language clean / readable and provides a remarkable stdlib. Rust tends to push as much as possible out to crates / the community for a number of legit reasons.

Go is, without a doubt, an amazing language but damn does it get boring.

devashishdxt commented 2 years ago

@devashishdxt Thanks for writing this, you beat me to it. About how long did it take you to write?

I've been writing Rust since last 4 years and now I'm quite comfortable with it. So, it took me around 1-2 hour to implement this. In addition to that, it took me around 2-3 hours to understand the current implementation (which was difficult because of missing comments). In total, it took me 4-5 hours.

pro465 commented 2 years ago

They have almost identical algorithms. Now we have a divergent algorithm, [..]

umm how? both of them spawn one task instead of two tasks as your previous rust prog did. i think the prev rust prog was more divergent.

ThePrimeagen commented 2 years ago

umm how? both of them spawn one task instead of two tasks as your previous rust prog did. i think the prev rust prog was more divergent.

As replied in the other thread. Gorilla executes one go routine per connection whereas the rust one has one long running tokio::task.

Are they the same? No, it was impossible to make exactly the same, but best effort was made to make them near identical. The gorilla server was to be as the server is in rust. It is its own running item in which emits out server connections, i tried to emulate this best effort in rust.

You made a PR that removes that, which makes the programs a bit more divergent but they were already divergent due to how things were handled anyways. I am fine making that change, though they are not equivalent.

pro465 commented 2 years ago

ok i guess, but again, the rust version as it is now, does not diverge more, it is actually closer now:

ThePrimeagen commented 2 years ago

@pro465 we are talking past each other.

ThePrimeagen commented 2 years ago

@chanced so here is my typical learning flow

  1. just learn some things about the language (how to use its std and what is available (non exhaustive))
  2. build a few cli applications (simple ones, no multithreading)
  3. build webservers

I am currently on 3 and this is my 4th attempt at playing around with the tungstenite repo. I find it very hard to reason about how things should be done in rust. But i can give this library a shot.

Also this PR is very interesting and i am learning a few things. @devashishdxt there are lots of things i just don't have a clear picture on. I really like the connection design but a bit out of the loop on this pin_project_lite business.

chanced commented 2 years ago

Rust is definitely a language I highly recommend reading books for first. That's a lot coming from me. If you've read The Book already, this is a great followup: Rust for Rustaceans.

ThePrimeagen commented 2 years ago

@chanced yeah, those are good. I have read Rust for Rustaceans and some Ohrly book (forget the name)

chanced commented 2 years ago

https://www.youtube.com/watch?v=DkMwYxfSYNQ (by the author of rust for rustaceans) may help with the pin_project_lite bit.

ThePrimeagen commented 2 years ago

https://www.youtube.com/watch?v=DkMwYxfSYNQ (by the author of rust for rustaceans) may help with the pin_project_lite bit.

watching! I have some builds that are taking 14 minutes right now, so its a great time to get some extra learnings in

devashishdxt commented 2 years ago

https://www.youtube.com/watch?v=DkMwYxfSYNQ (by the author of rust for rustaceans) may help with the pin_project_lite bit.

watching! I have some builds that are taking 14 minutes right now, so its a great time to get some extra learnings in

This video is one of the best resources to learn pinning.

jackos commented 2 years ago

Rust is definitely a language I highly recommend reading books for first.

A book I can't recommend enough for this type of thing is Zero to Production in Rust

There are so many options in the asynchronous space, and until now there haven't been good complete learning resources for it, being the main missing piece from the The Rust Book. Zero2Prod really bridges that gap, I'm very comfortable with web API's in Rust after reading it. @ThePrimeagen if you're interested check it out, I think you'll be amazed how simple and terse Rust can be for this type of thing.

devashishdxt commented 2 years ago

I guess the purpose is served. Closing this PR.

ThePrimeagen commented 2 years ago

I wanted to have yours up for a bit and review it next.

There technically isn't a reason to close just yet. This is a very nice version and provides a more "Enterprise" way of doing things (I mean this in a good way. Easier to test and separation of concerns)

I just only have so much time and was hurt today so I could not do much. Spent only about 2:50 at the computer

ThePrimeagen commented 2 years ago

Rust is definitely a language I highly recommend reading books for first.

A book I can't recommend enough for this type of thing is Zero to Production in Rust

There are so many options in the asynchronous space, and until now there haven't been good complete learning resources for it, being the main missing piece from the The Rust Book. Zero2Prod really bridges that gap, I'm very comfortable with web API's in Rust after reading it. @ThePrimeagen if you're interested check it out, I think you'll be amazed how simple and terse Rust can be for this type of thing.

This is great. Let me check it out. The async story is tough in rust, great to hear there are some nice resources out there

patternseek commented 2 years ago

The async story is tough in rust, great to hear there are some nice resources out there

Yeah async is really still fairly fresh in Rust and they're still smoothing off the rough edges.

ThePrimeagen commented 2 years ago

@patternseek well i am reading and trying to understand it better, but its pretty great!

I bet the recent changes to mutex probably make the code significantly faster as is.

Second, B3NNY also produced a very small, similar, version that runs super omega fast. going to do a recap on that soon, and i would like to read this code more. Its quite nice, props to @devashishdxt

jackos commented 2 years ago

going to do a recap on that soon

@ThePrimeagen that's awesome looking forward to that, loving all the Rust content on your channel recently