Conversation
Display is registered as an OnTick listener and the panel only stays on screen while it is being resent, so an open menu goes through this path 64 times a second per player. PrintToCenterHtml creates a game event, fires it and frees it, and doing that each time is most of what an open menu costs. The event is kept for as long as the menu is and refilled with the new markup instead, then freed in Close. Measured on a live server with a 12 item menu by alternating the two paths on every other render, so both meet the same conditions: 36.57us over 2466 sends against 27.54us over 2466. The labels and the builder go with it: AddPageOptions asks the localizer for Prev, Exit and Next unconditionally on every render, even when the buttons are not shown, and each of those runs ReplaceColorTags, which reflects over ChatColors. That is about 1us of the 37, so it is the small half of this, but none of it changes while the menu is open. Colours are still read per render, since a plugin can change them after the menu is built. Sending now returns early on an invalid player rather than throwing the way PrintToCenterHtml does, which suits something that runs every tick; Close already guarded the same way.
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.
CenterHtmlMenuInstance.Displayis registered as anOnTicklistener, and the panel only stays on screen while it is being resent, so an open menu goes through this path 64 times a second for every player looking at it.PrintToCenterHtmlcreates a game event, fires it and frees it. Doing that on every tick is most of what an open menu costs. The event is kept for as long as the menu is and refilled with the new markup instead, then freed inClose.Measurement
Taken on a live CS2 server with a 12 item menu, by alternating the two send paths on every other render so both meet the same conditions rather than running one after the other:
The same change in CounterStrikeSharp's own
CenterHtmlMenumeasured 36.81us against 29.02us, which is where the confidence in this number comes from — two separate code bases, same mechanism, same size of gain.The smaller half
AddPageOptionsasks the localizer forPrev,ExitandNexton every render, unconditionally, even when those buttons are not shown. Each of those calls goes throughReplaceColorTags, which reflects overChatColors. Benchmarked on its own that is 0.324us a call, so about 1us of the 37 — real but not the main cost. The labels are read once when the menu is opened instead, and oneStringBuilderis reused rather than allocated per render.Colours are still read on every render, since a plugin can change
CenterHtmlMenu_PrevPageColorand friends after the menu is built.One behaviour note
Sending returns early when the player is no longer valid rather than throwing, which is what
PrintToCenterHtmldoes through an internal guard that is not reachable from here. For something that runs every tick that seemed the better of the two, andClosealready checksPlayer.IsValidthe same way.Checked in game: menu opens, pages turn, items select, closes on select and on
!0.