valence-rs / valence

A Rust framework for building Minecraft servers.
http://valence.rs/
MIT License
2.83k stars 145 forks source link

Project Rewrite Tracking Issue #620

Closed rj00a closed 1 month ago

rj00a commented 5 months ago

Here are the steps that need to be taken to rewrite the project and get it updated to the latest version of the game, since folks were asking.

Should be done roughly in this order, one or more PRs per check.

luiswirth commented 2 months ago

Replace bevy ECS with evenio

no more bevy :(?

kehrazy commented 2 months ago

Replace bevy ECS with evenio

no more bevy :(?

kill bevy with FIRE! ๐Ÿ”ฅ

OvermindDL1 commented 2 months ago

Replace bevy ECS with evenio.

May I ask why? bevy_ecs outperforms it on its own benchmark everywhere except on random access, where bevy is twice the time (because it's a dual lookup for an entity->archetype->data), but of times so tiny they are just a pointer indirection cost anyway?

Here's my benchmark times using evenio's own benchmark with the latest version of both evenio and bevy_ecs (so git for evenio and 0.14.2 for bevy, no code changes needed for their benchmark code, it all just worked) for their benchmarks that have bevy in it:

add_components

(honestly I expect bevy to be slightly slower here as archetypes styles often are due to more copies, so... weird?):

Timer precision: 70 ns
add_components                fastest       โ”‚ slowest       โ”‚ median        โ”‚ mean          โ”‚ samples โ”‚ iters
โ”œโ”€ spawn_many_comps_40_bevy   1.662 ยตs      โ”‚ 44.46 ยตs      โ”‚ 1.705 ยตs      โ”‚ 2.952 ยตs      โ”‚ 100     โ”‚ 1000
โ•ฐโ”€ spawn_many_comps_n_evenio                โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”œโ”€ 1                       276.1 ns      โ”‚ 1.73 ยตs       โ”‚ 282.2 ns      โ”‚ 305.4 ns      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 2                       463.1 ns      โ”‚ 2.065 ยตs      โ”‚ 471.1 ns      โ”‚ 506.9 ns      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 3                       688.1 ns      โ”‚ 2.177 ยตs      โ”‚ 699.1 ns      โ”‚ 735.2 ns      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 5                       1.189 ยตs      โ”‚ 3.053 ยตs      โ”‚ 1.212 ยตs      โ”‚ 1.253 ยตs      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 10                      2.637 ยตs      โ”‚ 6.394 ยตs      โ”‚ 2.664 ยตs      โ”‚ 2.762 ยตs      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 15                      2.67 ยตs       โ”‚ 11.34 ยตs      โ”‚ 4.419 ยตs      โ”‚ 4.437 ยตs      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 20                      2.762 ยตs      โ”‚ 11.69 ยตs      โ”‚ 3.285 ยตs      โ”‚ 3.384 ยตs      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 25                      3.339 ยตs      โ”‚ 11.59 ยตs      โ”‚ 3.916 ยตs      โ”‚ 4.176 ยตs      โ”‚ 100     โ”‚ 1000
โ”œโ”€ 30                      5.099 ยตs      โ”‚ 16.01 ยตs      โ”‚ 5.131 ยตs      โ”‚ 5.406 ยตs      โ”‚ 100     โ”‚ 1000
โ•ฐโ”€ 40                      6.76 ยตs       โ”‚ 20.27 ยตs      โ”‚ 7.936 ยตs      โ”‚ 8.12 ยตs       โ”‚ 100     โ”‚ 1000

iter

(I expected bevy to be faster here, and it indeed was in much of it, but there seems to be a weird bit of noise... somewhere, it's not scaling for either of them as it should on the mandelbrot stuff... Also I find it odd they only look up a single component...):

Timer precision: 70 ns
iter                       fastest       โ”‚ slowest       โ”‚ median        โ”‚ mean          โ”‚ samples โ”‚ iters
โ”œโ”€ iter_mandelbrot_bevy                  โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚  โ•ฐโ”€ true                               โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚     โ”œโ”€ 1                 38.87 ยตs      โ”‚ 106.5 ยตs      โ”‚ 64.03 ยตs      โ”‚ 66.08 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 2                 48.01 ยตs      โ”‚ 130.8 ยตs      โ”‚ 71.97 ยตs      โ”‚ 72.85 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 3                 63.36 ยตs      โ”‚ 133.7 ยตs      โ”‚ 97.65 ยตs      โ”‚ 98.05 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 8                 127 ยตs        โ”‚ 213.1 ยตs      โ”‚ 154.8 ยตs      โ”‚ 156.5 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 16                199.2 ยตs      โ”‚ 598.1 ยตs      โ”‚ 239.2 ยตs      โ”‚ 277.9 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 32                220.5 ยตs      โ”‚ 828.7 ยตs      โ”‚ 337.8 ยตs      โ”‚ 349.6 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 64                431.3 ยตs      โ”‚ 673.7 ยตs      โ”‚ 540 ยตs        โ”‚ 538.6 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 128               454.5 ยตs      โ”‚ 1.673 ms      โ”‚ 759.5 ยตs      โ”‚ 773.4 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 256               834.4 ยตs      โ”‚ 2.127 ms      โ”‚ 1.437 ms      โ”‚ 1.459 ms      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 512               2.077 ms      โ”‚ 3.302 ms      โ”‚ 2.748 ms      โ”‚ 2.764 ms      โ”‚ 100     โ”‚ 100
โ”‚     โ•ฐโ”€ 1024              2.737 ms      โ”‚ 9.691 ms      โ”‚ 5.098 ms      โ”‚ 4.412 ms      โ”‚ 100     โ”‚ 100
โ”œโ”€ iter_mandelbrot_evenio                โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚  โ•ฐโ”€ true                               โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚     โ”œโ”€ 1                 56.97 ยตs      โ”‚ 1.506 ms      โ”‚ 111.4 ยตs      โ”‚ 156.6 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 2                 63.31 ยตs      โ”‚ 775.3 ยตs      โ”‚ 186.8 ยตs      โ”‚ 189.3 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 3                 62.99 ยตs      โ”‚ 503.5 ยตs      โ”‚ 78.32 ยตs      โ”‚ 128.9 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 8                 74.49 ยตs      โ”‚ 375.4 ยตs      โ”‚ 141.4 ยตs      โ”‚ 159.8 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 16                90.65 ยตs      โ”‚ 978.5 ยตs      โ”‚ 229.7 ยตs      โ”‚ 242.3 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 32                110.7 ยตs      โ”‚ 919.3 ยตs      โ”‚ 243.2 ยตs      โ”‚ 247 ยตs        โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 64                145 ยตs        โ”‚ 1.086 ms      โ”‚ 337.8 ยตs      โ”‚ 343.9 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 128               227.7 ยตs      โ”‚ 800.8 ยตs      โ”‚ 449.3 ยตs      โ”‚ 465.5 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 256               411.8 ยตs      โ”‚ 2.352 ms      โ”‚ 636.3 ยตs      โ”‚ 662.1 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 512               687.1 ยตs      โ”‚ 1.418 ms      โ”‚ 709 ยตs        โ”‚ 765.7 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ•ฐโ”€ 1024              1.291 ms      โ”‚ 2.342 ms      โ”‚ 1.357 ms      โ”‚ 1.464 ms      โ”‚ 100     โ”‚ 100
โ”œโ”€ iter_simple_bevy                      โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚  โ”œโ”€ false                              โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚  โ”‚  โ”œโ”€ 1                 7.806 ns      โ”‚ 44.63 ns      โ”‚ 11.79 ns      โ”‚ 11.98 ns      โ”‚ 100     โ”‚ 25600
โ”‚  โ”‚  โ”œโ”€ 10                18.97 ns      โ”‚ 51.59 ns      โ”‚ 18.99 ns      โ”‚ 19.31 ns      โ”‚ 100     โ”‚ 51200
โ”‚  โ”‚  โ”œโ”€ 100               64.47 ns      โ”‚ 135.7 ns      โ”‚ 64.48 ns      โ”‚ 65.53 ns      โ”‚ 100     โ”‚ 12800
โ”‚  โ”‚  โ”œโ”€ 1000              630.3 ns      โ”‚ 2.205 ยตs      โ”‚ 630.5 ns      โ”‚ 685.9 ns      โ”‚ 100     โ”‚ 800
โ”‚  โ”‚  โ”œโ”€ 10000             6.298 ยตs      โ”‚ 25.85 ยตs      โ”‚ 12.55 ยตs      โ”‚ 10.02 ยตs      โ”‚ 100     โ”‚ 100
โ”‚  โ”‚  โ”œโ”€ 100000            53.55 ยตs      โ”‚ 150.1 ยตs      โ”‚ 125.1 ยตs      โ”‚ 99 ยตs         โ”‚ 100     โ”‚ 100
โ”‚  โ”‚  โ•ฐโ”€ 1000000           594 ยตs        โ”‚ 1.416 ms      โ”‚ 1.115 ms      โ”‚ 1.034 ms      โ”‚ 100     โ”‚ 100
โ”‚  โ•ฐโ”€ true                               โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚     โ”œโ”€ 1                 1.789 ยตs      โ”‚ 51.56 ยตs      โ”‚ 1.958 ยตs      โ”‚ 5.421 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 10                4.938 ยตs      โ”‚ 41.98 ยตs      โ”‚ 9.783 ยตs      โ”‚ 11.13 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 100               13.95 ยตs      โ”‚ 74.89 ยตs      โ”‚ 18.28 ยตs      โ”‚ 21.41 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 1000              20.77 ยตs      โ”‚ 90.14 ยตs      โ”‚ 30.4 ยตs       โ”‚ 33.6 ยตs       โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 10000             25.73 ยตs      โ”‚ 186 ยตs        โ”‚ 42.01 ยตs      โ”‚ 44.17 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ”œโ”€ 100000            67.79 ยตs      โ”‚ 240.5 ยตs      โ”‚ 111.2 ยตs      โ”‚ 121.2 ยตs      โ”‚ 100     โ”‚ 100
โ”‚     โ•ฐโ”€ 1000000           217.9 ยตs      โ”‚ 937.3 ยตs      โ”‚ 476 ยตs        โ”‚ 477.7 ยตs      โ”‚ 100     โ”‚ 100
โ•ฐโ”€ iter_simple_evenio                    โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”œโ”€ false                              โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”‚  โ”œโ”€ 1                 30.02 ns      โ”‚ 658.6 ns      โ”‚ 30.38 ns      โ”‚ 131.9 ns      โ”‚ 100     โ”‚ 25600
โ”‚  โ”œโ”€ 10                37.88 ns      โ”‚ 86.93 ns      โ”‚ 40.53 ns      โ”‚ 41.42 ns      โ”‚ 100     โ”‚ 25600
โ”‚  โ”œโ”€ 100               151 ns        โ”‚ 271 ns        โ”‚ 151.4 ns      โ”‚ 153.3 ns      โ”‚ 100     โ”‚ 3200
โ”‚  โ”œโ”€ 1000              1.284 ยตs      โ”‚ 4.563 ยตs      โ”‚ 1.286 ยตs      โ”‚ 1.465 ยตs      โ”‚ 100     โ”‚ 400
โ”‚  โ”œโ”€ 10000             12.57 ยตs      โ”‚ 33.79 ยตs      โ”‚ 25.07 ยตs      โ”‚ 19.54 ยตs      โ”‚ 100     โ”‚ 100
โ”‚  โ”œโ”€ 100000            106.8 ยตs      โ”‚ 308.9 ยตs      โ”‚ 220.3 ยตs      โ”‚ 194.3 ยตs      โ”‚ 100     โ”‚ 100
โ”‚  โ•ฐโ”€ 1000000           1.341 ms      โ”‚ 4.775 ms      โ”‚ 2.521 ms      โ”‚ 2.478 ms      โ”‚ 100     โ”‚ 100
โ•ฐโ”€ true                               โ”‚               โ”‚               โ”‚               โ”‚         โ”‚
โ”œโ”€ 1                 59.16 ns      โ”‚ 115.6 ns      โ”‚ 59.24 ns      โ”‚ 64.57 ns      โ”‚ 100     โ”‚ 12800
โ”œโ”€ 10                12.66 ยตs      โ”‚ 260.4 ยตs      โ”‚ 34.37 ยตs      โ”‚ 48.77 ยตs      โ”‚ 100     โ”‚ 100
โ”œโ”€ 100               20.55 ยตs      โ”‚ 252.3 ยตs      โ”‚ 31.27 ยตs      โ”‚ 39.79 ยตs      โ”‚ 100     โ”‚ 100
โ”œโ”€ 1000              42.22 ยตs      โ”‚ 201.3 ยตs      โ”‚ 89.62 ยตs      โ”‚ 94.8 ยตs       โ”‚ 100     โ”‚ 100
โ”œโ”€ 10000             58.51 ยตs      โ”‚ 438.7 ยตs      โ”‚ 118.2 ยตs      โ”‚ 152.4 ยตs      โ”‚ 100     โ”‚ 100
โ”œโ”€ 100000            79.11 ยตs      โ”‚ 710.3 ยตs      โ”‚ 232.8 ยตs      โ”‚ 257.6 ยตs      โ”‚ 100     โ”‚ 100
โ•ฐโ”€ 1000000           289 ยตs        โ”‚ 2.196 ms      โ”‚ 765 ยตs        โ”‚ 866.6 ยตs      โ”‚ 100     โ”‚ 100

random_access

(I expect bevy to be twice the cost here since 2 pointer indirections instead of one for the secondary index/cache, but again, these are so fast that the times are just noise, the test has to have a million entities to even get to the times it's at, which is literally just memory pressure timings at this point as they run literally no code beyond a black_box access in the tests, doing any work at all will flatten this):

Timer precision: 29 ns
random_access            fastest       โ”‚ slowest       โ”‚ median        โ”‚ mean          โ”‚ samples โ”‚ iters
โ”œโ”€ random_access_bevy    1.842 ms      โ”‚ 3.721 ms      โ”‚ 2.02 ms       โ”‚ 2.18 ms       โ”‚ 100     โ”‚ 100
โ•ฐโ”€ random_access_evenio  917.1 ยตs      โ”‚ 1.279 ms      โ”‚ 1.052 ms      โ”‚ 1.056 ms      โ”‚ 100     โ”‚ 100
dyc3 commented 2 months ago

I can't find the discussion right now, but this has been discussed before. We are looking to replace bevy primarily because of development ergonomics. A lot of the code we write relies very heavily on events that trigger logic.

JackCrumpLeys commented 2 months ago

I personally don't think any developers are motivated to continue this rewrite. At the moment @rj00a has mysteriously disappeared and I seem to be the main person still working on it. My development effort is currently focused on 1.21 and after that I would rather add features then undertake a rewrite. If someone with a lot of spare time and motivation shows up this might happen but it seems unlikely.

giantcow commented 2 months ago

The evenio docs eludes to some of the reasoning https://docs.rs/evenio/latest/evenio/tutorial/#why-evenio

OvermindDL1 commented 2 months ago

A lot of the code we write relies very heavily on events that trigger logic.

The evenio docs eludes to some of the reasoning https://docs.rs/evenio/latest/evenio/tutorial/#why-evenio

bevy_ecs also handles events, though it does it in a more controllable way with less overhead as they are batched and run at-once in a system with parallel support. What it looks like evenio does from my little of experimenting with it is it calls event handlers immediately, which is equivalent to bevy_ecs's ability to run a system on demand (many times in a frame if you so wish), except bevy's has less virtual dispatch overhead as the archetypes can be immediately known, statically if so wished (or even dynamically dispatched if you wanted to go that way, ala' how evenio does it).

I experimented with evenio but I didn't see any feature it had that bevy_ecs lacked, and bevy_ecs has a great many features that it lacks, and it had no performance boost to offset it either (and indeed you lose out in a great amount of performance in many areas with multi-threading as it can only multi-thread 'within' a system (if the user chooses to), not 'across' systems, and you cannot often multi-thread within a system and even most of the time when you can it's not worth it due to the task dispatch overhead and the low amount of iterations within most systems).

But yeah, in short if you want to run something to handle an 'event' now then bevy has run-on-demand systems for that, but honestly you shouldn't except in specialized cases (which do exist), that's needless performance overhead for no reason otherwise and makes it harder to follow 'when' something happens.

dyc3 commented 1 month ago

I'm going to close and unpin this issue since the main driver behind it (@rj00a) is MIA for now. We can always reopen it later.

IMO, the changes suggested in this issue (particularly the switch to evenio) are a non-starter because it requires too much effort. We are better off continuing to iterate on the current version.