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

Introduce a Timer Snapshot Mechanism #339

Merged
merged 2 commits into from
Jun 11, 2020

Conversation

CryZe
Copy link
Collaborator

@CryZe CryZe commented Jun 10, 2020

This introduces the ability to create snapshots of the timer. At the moment of snapshot creation the current time of the timer is evaluated. The snapshot then represents the timer with the current time frozen at that specific time. This allows layout state evaluation and other calculations to work with a consistent timer that is entirely frozen, allowing for more consistent results. However almost more importantly, this reduces the amount of times we need to take time stamps from the underlying system, improving the performance a bit.

https://i.imgur.com/vDkucUu.png

In the web the performance improvement is even more significant. There the layout state calculation improved from 8.5us to 5us.

This introduces the ability to create snapshots of the timer. At the
moment of snapshot creation the current time of the timer is evaluated.
The snapshot then represents the timer with the current time frozen at
that specific time. This allows layout state evaluation and other
calculations to work with a consistent timer that is entirely frozen,
allowing for more consistent results. However almost more importantly,
this reduces the amount of times we need to take time stamps from the
underlying system, improving the performance a bit.

![https://i.imgur.com/vDkucUu.png](https://i.imgur.com/vDkucUu.png)

In the web the performance improvement is even more significant. There
the layout state calculation improved from 8.5us to 5us.
@CryZe CryZe added enhancement An improvement for livesplit-core. performance Affects the performance of the code. labels Jun 10, 2020
@CryZe CryZe requested a review from wooferzfg June 10, 2020 15:57
Copy link
Member

@wooferzfg wooferzfg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this makes sense to me.

Something that I'm curious about - have we thought about how Snapshots will fit in with Time Sources (#90) once those are implemented? I think that the Time Sources would allow us to also freeze the current_time calls that we make from within Timer, such as when splitting:

let current_time = self.current_time();

src/timing/timer/mod.rs Outdated Show resolved Hide resolved
@CryZe
Copy link
Collaborator Author

CryZe commented Jun 11, 2020

The Synchronization Protocol and the Time Sources are mostly concerned about how you modify / control the timer. We need some low level mechanism that does indeed affect

let current_time = self.current_time();

For perceiving the timer however the snapshot mechanism is what we want. I don't think this clashes with the design of manipulating the timer.

Co-authored-by: wooferzfg <spapushin@gmail.com>
@CryZe CryZe merged commit 71b5cc8 into LiveSplit:master Jun 11, 2020
@CryZe CryZe deleted the snapshot-mechanism branch June 11, 2020 12:49
@CryZe CryZe added this to the v0.12 milestone Jun 11, 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An improvement for livesplit-core. performance Affects the performance of the code.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants