Skip to content

Replace ArrayList<Long> tick buffer with primitive ring buffer#17

Merged
Tre5et merged 13 commits intoTre5et:mainfrom
Vianpyro:primitive-ring-buffer
Apr 25, 2026
Merged

Replace ArrayList<Long> tick buffer with primitive ring buffer#17
Tre5et merged 13 commits intoTre5et:mainfrom
Vianpyro:primitive-ring-buffer

Conversation

@Vianpyro
Copy link
Copy Markdown
Contributor

Closes #12

Changes

  • Add TickLengthBuffer class: a fixed-size long[] ring buffer with add(), averageMillis(), and reset() methods
  • Update ServerHandler to use TickLengthBuffer instead of ArrayList<Long>, change getTickLengths() from static to instance method
  • Add getServerHandler() getter in AdaptiveViewMod to expose the ServerHandler instance
  • Update MinecraftServerMixin to access the buffer through AdaptiveViewMod.getServerHandler() instead of the former static method
  • Remove MathTools.longArrayAverage() dependency for tick length calculation (now handled internally by the buffer)

Why

  • Eliminates per-tick long -> Long autoboxing
  • Replaces unbounded list growth + bulk clear() with a fixed-size circular write
  • Buffer is sized to updateRate, matching the exact number of samples needed per cycle

Note

I haven't benchmarked this beyond verifying it compiles and builds successfully. The optimization is straightforward: replacing boxed Long allocations and unbounded list growth with a fixed-size primitive array, so the improvement is a matter of fewer allocations per tick rather than something easily measurable in isolation. The behavioral logic (MSPT averaging) remains identical.

@Vianpyro Vianpyro marked this pull request as ready for review April 21, 2026 01:06
@Tre5et Tre5et merged commit dee0e29 into Tre5et:main Apr 25, 2026
1 check passed
@Tre5et
Copy link
Copy Markdown
Owner

Tre5et commented Apr 25, 2026

These changes are well implemented and probably provide some performance improvement. I have just removed the now no longer needed math tools. Since I am not currently working on any changes that this could be included with, I will create an release only containing this change soon.

@Tre5et
Copy link
Copy Markdown
Owner

Tre5et commented Apr 25, 2026

I have unfortunately discovered an issue with the implementation. Since the ring buffer is only initialized once, it always has the size of the default update rate. Rules can however change the update rate, which means that for a longer update rate, not all tick times are considered. I have reverted the changes, until a solution to this is found.

I would suggest initializing the buffer to a constant size, independent of update rate and saving the average in a dynamically sized list on overflow. When the total average is queried, these saved averages as well as the tick times currently in the buffer can then be considered.

If you have a better solution feel free to implement this as well though.

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

Successfully merging this pull request may close these issues.

Replace ArrayList<Long> tick buffer with primitive ring buffer

2 participants