TGViewer
Telegram github commits and releases Telegram github commits and releases @tgappsupdates · 4.54K subscribers
Post #20600 45
UnigramDev/Unigram/composer-typing-performance • 0827fe2 • 2 files, +59/-0
Add a profiler for scoped timings

Begin and End are [Conditional("INSTRUMENTATION")] like Instrumentation.Register,
so a probe can sit permanently at a call site and compiles out of every build
that doesn't define the symbol. A helper returning a timestamp cannot do that:
the reading itself would stay in the hot path, which is where these get placed.

Scopes nest and are reported indented, so an outer scope shows what it contains.
End unwinds to its own label, so a return between a pair reports the abandoned
scopes rather than silently charging the rest of the run to them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

UnigramDev/Unigram/composer-typing-performance • fc25f0d • 1 files, +122/-109
Probe the document once instead of walking it on every keystroke

UpdateFormat, UpdateCustomEmoji and UpdateBlocks each walked the whole document
on every keystroke. The editor breaks character format runs at every space, so
the first of those was O(words) round trips into the text host per character
typed.

TOM reports a property as undefined when it isn't uniform over a range, so a
single read over the whole story says whether there is anything to walk for at
all: no hidden text means no custom emoji, a uniform SpaceAfter of zero means no
blockquote, and a document already at the regular size has no font size to fix.

Alongside that: the ranges these walk with are kept and moved rather than
allocated on each pass, since every ITextRange is a COM object; applying
entities in SetText reuses one range instead of one per entity; and UpdateBlocks
removed stale blockquote decorations with an index loop that skipped every other
element.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

UnigramDev/Unigram/composer-typing-performance • dc8291a • 1 files, +26/-6
Stop allocating per character in the emoticon replacement

OnCharacterReceived runs for every character typed. It built a byte array and a
string just to recover the first char of the code point, then used Max and a
capturing FirstOrDefault over the candidates. The first char comes straight off
the code point now and the two LINQ calls are loops.

The Consolas check moved behind the candidate lookup, so a keystroke that can't
end an emoticon no longer pays for a call into the text host, and EndsWith is
ordinal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

UnigramDev/Unigram/composer-typing-performance • eb2e555 • 1 files, +14/-12
Don't recreate every custom emoji source on each keystroke

UpdateEntities assigned a new CustomEmojiFileSource to every player on every
text change. Each one sends getCustomEmojiStickers from its constructor and
re-runs AnimatedImage.Load. It only assigns when the id actually differs now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

#unigram
More from @tgappsupdates
  1. Oct 13, 2026telegramdesktop/tdesktop/dev • 5acda87 • 2 files, +10/-4 [ai] Raised the cross-review roun…
  2. Oct 13, 2026telegramdesktop/tdesktop/dev • 3c9f6ee • 1 files, +8/-8 Bump actions/download-artifact fro…
  3. Oct 13, 2026TGX-Android/Telegram-X/main • e8a46a1 • 3 files, +27/-7 Update `.gitmodules` #tgxandroid
  4. Oct 13, 2026UnigramDev/Unigram/develop • 7842fff • 5 files, +1215/-148 Group the rich editor toolbar's…
  5. Oct 13, 2026UnigramDev/Unigram/develop • c04c03a • 2 files, +53/-9 Map spell checking and collapsible…
  6. Oct 13, 2026UnigramDev/Unigram/develop • 5b57a69 • 1 files, +1/-0 Fix event unsubscribe UnigramDev/Uni…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →