Visitar URL original
chore: general performance improvements by TaylorHo · Pull Request #1932 · molstar/molstar · GitHub
Skip to content

chore: general performance improvements - #1932

Open
TaylorHo wants to merge 1 commit into
molstar:masterfrom
TaylorHo:chore/performance-improvements
Open

TaylorHo wants to merge 1 commit into
molstar:masterfrom
TaylorHo:chore/performance-improvements

Conversation

@TaylorHo

Copy link
Copy Markdown
Collaborator

Description

Optimized the viewer rendering hot path to reduce redundant GPU/CPU work during rendering.

Changes

  • Skip redundant uniform uploads when ValueCell values have not changed.
  • Batch shared uniform and texture updates per program switch instead of per render object.
  • Cache active texture units and bound textures to avoid redundant GL calls.
  • Cache culling results when grid/LOD state has not changed.
  • Reuse the light-direction buffer and fix its upload size.

Results

  • 71% reduction in Canvas3D.render CPU time.
  • 72% reduction in DrawPass.render CPU time.
  • 54% reduction in multisample rendering CPU time.
  • 28% reduction in steady-state CPU mean and 52% reduction in CPU median.
  • 34% reduction in maximum GPU frame time.
  • 48% reduction in maximum CPU frame time.
  • 94.1% of uniform uploads skipped in the final frame.

These changes significantly reduce CPU rendering overhead and improve worst-case frame hitches, while also providing moderate GPU improvements.

Actions

  • Added description of changes to the [Unreleased] section of CHANGELOG.md
  • Updated headers of modified files
  • Added my name to package.json's contributors
  • (Optional but encouraged) Improved documentation in docs

@arose

arose commented Sep 12, 2026

Copy link
Copy Markdown
Member

Thank you @TaylorHo. This looks interesting. Please split this into multiple PRs that target a specific kind or area of optimization.

I would be especially curious to see what effect tracking texture units in the state has and the extra sorting of scene renderables. Please leave the renderable culling out, I am about to do a PR that handles it a bit more general so it also works for multi-sample (will ping you as a reviewer).

I don't think the uniform optimization works. You will need to re-upload them when ever the program changes and are careful not to do so unnecessarily, see RenderItem.render. What helps with reducing uniform calls is UBOs (webgl2 only). I have a prototype for it and it helps a little here.

@dsehnal dsehnal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for going through this.

Comment thread src/mol-gl/webgl/state.ts

reset: () => {
enabledCapabilities = {};
for (const k of Object.keys(enabledCapabilities)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this really faster than allocating a single new object?

Comment thread src/mol-state/state.ts

// Fast path: same number and all current refs are still in effective.
if (current.length === effective.length) {
const effectiveSet = new Set(effective);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Have a reusable set that you clear?

@TaylorHo

Copy link
Copy Markdown
Collaborator Author

Thank you @TaylorHo. This looks interesting. Please split this into multiple PRs that target a specific kind or area of optimization.

Sure! I'll review your comments and split this into smaller PRs this week. Thanks in advance for the invite to the repo!

dsehnal added a commit that referenced this pull request Oct 24, 2026
…rial maps, reused maps) (#2042)

- CIF: toDatabase with aliases flattens the frame once for all tables
- chain-id, entity-id, operator-hkl color themes cache their serial maps in the structure's currentPropertyData
  (entity-id on the structure itself, its source serials come from that structure's models)
- Stats.handleElement and Loci.extendToRadius reuse their maps; extendToRadius keeps a fresh index array per
  unit, makeIndexSet keeps it as the loci's indices
- relinkCells: a Set for the fast path only past 8 dependencies

Left out from #1932: the GL and Canvas3D changes (WebGPU work), the representation renderObjects cache (stale when
only `visuals` changes), the shared scratch arrays (aliased into returned loci, or across awaits), the CIF list-column
row cache, the PDB helix loop.

Co-authored-by: Taylor Hoffmann <taylor@hoffmann.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

3 participants