Skip to content

[Performance] Reduce allocations in TextShaperImpl by reusing HarfBuzz Buffer #18892

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

Merged
merged 1 commit into from
May 31, 2025

Conversation

dme-compunet
Copy link
Contributor

What does the pull request do?

Currently, a new HarfBuzz Buffer is allocated in TextShaperImpl for every text shaping operation. This can be avoided by reusing a single buffer and calling Reset before each shaping operation.

What is the current behavior?

What is the updated/expected behavior with this PR?

How was the solution implemented (if it's not obvious)?

Checklist

Breaking changes

Obsoletions / Deprecations

Fixed issues

@Gillibald
Copy link
Contributor

Have you measured this? Resetting the buffer might be more costly.

@Gillibald
Copy link
Contributor

It looks like buffer create calls reset, so this should be fine: https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-buffer.cc#L762

Copy link
Contributor

@Gillibald Gillibald left a comment

Choose a reason for hiding this comment

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

LGTM

@Gillibald Gillibald added the backport-candidate-11.3.x Consider this PR for backporting to 11.3 branch label May 20, 2025
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 12.0.999-cibuild0056607-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@kerams
Copy link
Contributor

kerams commented May 20, 2025

Is there a chance that this runs on ephemeral threads, and leaks memory over time since there is no dispose? Or does the runtime automatically dispose of thread static values, if possible, when a thread is destroyed?

@Gillibald
Copy link
Contributor

We can make the ITextShaper disposable and the buffer does not need to be static.

@MrJul
Copy link
Member

MrJul commented May 31, 2025

Is there a chance that this runs on ephemeral threads, and leaks memory over time since there is no dispose? Or does the runtime automatically dispose of thread static values, if possible, when a thread is destroyed?

The runtime won't dispose of the values, but will finalize them, which would reclaim the native resources.

Anyways, I wouldn't worry too much: 99.9% of text shaping operations will occur on the UI thread. We're already caching some values using thread static fields in other parts of the text layout engine, for example in TextFormatterImpl.

@MrJul MrJul added this pull request to the merge queue May 31, 2025
Merged via the queue into AvaloniaUI:master with commit 3e01a53 May 31, 2025
11 checks passed
@MrJul MrJul added backported-11.3.x and removed backport-candidate-11.3.x Consider this PR for backporting to 11.3 branch labels Jun 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants