Implement updating the Layout States#334
Merged
CryZe merged 2 commits intoLiveSplit:masterfrom May 30, 2020
Merged
Conversation
So far we've always discarded the layout states, but since we want to calculate layout states every frame, it makes a lot more sense to keep the layout state around and just update it. All of the original API is retained, so you are not forced to actually update your layout states. However the code for creating a new layout state now initializes a default state and updates it, instead of directly creating it correctly. This might slightly slow down initial creation, but we don't want to basically duplicate the same code across initial creation and updating. By doing this an average frame now has 0 allocations, reallocations and deallocations. We are seeing speedups of around 3x - 5x in the newly added benchmarks. This also introduces a new `ClearVec` type that behaves like a normal `Vec` but when clearing it, instead of dropping all the elements, it just keeps them around and clears them instead. So if you had a `Vec<String>` and cleared it, all the Strings would get deallocated, while a `ClearVec<String>` would keep them around and just set their length back to 0. We use this in a few places to reduce the chances of us needing to allocate new memory. It might make sense to move it into its own crate eventually as this should be a useful type for any kind of Rust code.
16dd23e to
f7360cd
Compare
wooferzfg
reviewed
May 30, 2020
Co-authored-by: wooferzfg <spapushin@gmail.com>
17993c5 to
751682f
Compare
wooferzfg
approved these changes
May 30, 2020
CryZe
added a commit
to CryZe/LiveSplitOne
that referenced
this pull request
Jun 14, 2020
This updates livesplit-core which brings a variety of performance improvements: - The Layout State is now being reused and thus most frames don't require any heap allocations anymore. However we still serialize everything over into a JSON string for now, which puts a lot of garbage on the JS heap. LiveSplit/livesplit-core#334 - The frequent performance.now() calls we do, first lookup up the window and performance object every time. This tripled the amount of calls we do over into JavaScript, with each call into JavaScript being quite expensive in Chrome. LiveSplit/livesplit-core#335 - By introducing a timer snapshot mechanism we further reduce the calls to performance.now() to a single time. LiveSplit/livesplit-core#339 - Rust 1.44 regressed the performance of 128-bit integer multiplications by accident. Those are used for hashing the comparisons when looking up the times for a comparison, which is something we do very frequently. We however don't have many comparisons, so a simple Vec that we loop through is a bit faster, even in native code, and quite a bit faster in the web, because of the Rust 1.44 regression. LiveSplit/livesplit-core#338 - We delay registering the Gamepad Hook Interval until the first gamepad button is registered. Most people won't use a gamepad, so the interval just waits cpu time for no reason. LiveSplit/livesplit-core#340
CryZe
added a commit
that referenced
this pull request
Nov 14, 2021
- Runs now support custom variables that are key value pairs that either the user can specify in the run editor or are provided by a script like an auto splitter. [#201](#201) - There is now an option in the run editor to generate a comparison based on a user specified goal time. This uses the same algorithm as the `Balanced PB` comparison but with the time specified instead of the personal best. [#209](#209) - Images internally are now stored as is without being reencoded as Base64 which was done before in order to make it easier for the web LiveSplit One to display them. [#227](#227) - The Splits.io API is now available under the optional `networking` feature. [#236](#236) - All key value based components share the same component state type now. [#257](#257) - The crate now properly supports `wasm-bindgen` and `WASI`. [#263](#263) - There is now a dedicated component for displaying the comparison's segment time. [#264](#264) - Compiling the crate without `std` is now supported. Most features are not supported at this time though. [#270](#270) - [`Splitterino`](https://github.com/prefixaut/splitterino) splits can now be parsed. [#276](#276) - The `Timer` component can now show a segment timer instead. [#288](#288) - Gamepads are now supported on the web. [#310](#310) - The underlying "skill curve" that the `Balanced PB` samples is now exposed in the API. [#330](#330) - The layout states can now be updated, which means almost all of the allocations can be reused from the previous frame. This is a lot faster. [#334](#334) - In order to calculate a layout state, the timer now provides a snapshot mechanism that ensures that the layout state gets calculated at a fixed point in time. [#339](#339) - Text shaping is now done via `rustybuzz` which is a port of `harfbuzz`. [#378](#378) - Custom fonts are now supported. [#385](#385) - The renderer is not based on meshes anymore that are suitable for rendering with a 3D graphics API. Instead the renderer is now based on paths, which are suitable for rendering with a 2D graphics API such as Direct2D, Skia, HTML Canvas, and many more. The software renderer is now based on `tiny-skia` which is so fast that it actually outperforms any other rendering and is the recommended way to render. [#408](#408) - Remove support for parsing `worstrun` splits. `worstrun` doesn't support splits anymore, so `livesplit-core` doesn't need to keep its parsing support. [#411](#411) - Remove support for parsing `Llanfair 2` splits. `Llanfair 2` was never publicly available and is now deleted entirely. [#420](#420) - Hotkeys are now supported on macOS. [#422](#422) - The renderer is now based on two layers. A bottom layer that rarely needs to be rerendered and the top layer that needs to be rerendered on every frame. Additionally the renderer is now a scene manager which manages a scene that an actual rendering backend can then render out. [#430](#430) - The hotkeys are now based on the [UI Events KeyboardEvent code Values](https://www.w3.org/TR/uievents-code/) web standard. [#440](#440) - Timing is now based on `CLOCK_BOOTTIME` on Linux and `CLOCK_MONOTONIC` on macOS and iOS. This ensures that all platforms keep tracking time while the operating system is in a suspended state. [#445](#445) - Segment time columns are now formatted as segment times. [#448](#448) - Hotkeys can now be resolved to the US keyboard layout. [#452](#452) - They hotkeys are now based on `keydown` instead of `keypress` in the web. `keydown` handles all keys whereas `keypress` only handles visual keys and is also deprecated. [#455](#455) - Hotkeys can now be resolved to the user's keyboard layout on both Windows and macOS. [#459](#459) and [#460](#460) - The `time` crate is now used instead of `chrono` for keeping track of time. [#462](#462) - The scene manager now caches a lot more information. This improves the performance a lot as it does not need to reshape the text on every frame anymore, which is a very expensive operation. [#466](#466) and [#467](#467) - The hotkeys on Linux are now based on `evdev`, which means Wayland is now supported. Additionally the hotkeys are not consuming the key press anymore. [#474](#474) - When holding down a key, the hotkey doesn't repeat anymore on Linux, macOS and WebAssembly. The problem still occurs on Windows at this time. [#475](#475) and [#476](#476)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
So far we've always discarded the layout states, but since we want to calculate layout states every frame, it makes a lot more sense to keep the layout state around and just update it. All of the original API is retained, so you are not forced to actually update your layout states. However the code for creating a new layout state now initializes a default state and updates it, instead of directly creating it correctly. This might slightly slow down initial creation, but we don't want to basically duplicate the same code across initial creation and updating.
By doing this an average frame now has 0 allocations, reallocations and deallocations. We are seeing speedups of around 3x - 5x in the newly added benchmarks.
This also introduces a new
ClearVectype that behaves like a normalVecbut when clearing it, instead of dropping all the elements, it just keeps them around and clears them instead. So if you had aVec<String>and cleared it, all the Strings would get deallocated, while aClearVec<String>would keep them around and just set their length back to 0. We use this in a few places to reduce the chances of us needing to allocate new memory. It might make sense to move it into its own crate eventually as this should be a useful type for any kind of Rust code.Resolves #54