[Performance] Replace std::vector with more lightweight structure in RenderData::GetPatternId #14403

Open
opened 2026-01-31 04:09:21 +00:00 by claunia · 8 comments
Owner

Originally created by @skyline75489 on GitHub (Jul 6, 2021).

This is about the scrolling test in #10563. A simplified repro would be:

time bash -c 'yes | head -n1000000'

which takes 7-8s with windows terminal and 300ms with gnome terminal.

Test case provided by @lhecker.

These lines show up in the hot paths of the trace of OpenConsole:

https://github.com/microsoft/terminal/blob/main/src/renderer/base/renderer.cpp#L788

image

It appears that simply constructing empty std::vector (empty because this is in conhost/OpenConsole) is quite expensive.

CC @PankajBhojwani

Originally created by @skyline75489 on GitHub (Jul 6, 2021). This is about the scrolling test in #10563. A simplified repro would be: ```bash time bash -c 'yes | head -n1000000' ``` which takes 7-8s with windows terminal and 300ms with gnome terminal. Test case provided by @lhecker. These lines show up in the hot paths of the trace of `OpenConsole`: https://github.com/microsoft/terminal/blob/main/src/renderer/base/renderer.cpp#L788 ![image](https://user-images.githubusercontent.com/4710575/124551976-7fac6600-de65-11eb-892c-982f5e8ab85b.png) It appears that simply constructing empty `std::vector` (empty because this is in conhost/OpenConsole) is quite expensive. CC @PankajBhojwani
claunia added the Help WantedArea-RenderingIssue-TaskProduct-MetaArea-Performance labels 2026-01-31 04:09:21 +00:00
Author
Owner

@skyline75489 commented on GitHub (Jul 6, 2021):

Proposed solution:

Seem to me the number of possible pattern ids returned should be limited. For example if we limit it to max 2 pattern ids, we can use a simple structure:

struct {
    size_t primaryId;
    size_t secondaryId;
} PatternIds
@skyline75489 commented on GitHub (Jul 6, 2021): Proposed solution: Seem to me the number of possible pattern ids returned should be limited. For example if we limit it to max 2 pattern ids, we can use a simple structure: ```c++ struct { size_t primaryId; size_t secondaryId; } PatternIds ```
Author
Owner

@DHowett commented on GitHub (Jul 6, 2021):

Seem to me the number of possible pattern ids returned should be limited.

Why's that? Somebody could conceivably have many such IDs.

Last time we saw a vector being a performance drain we switched it to an unordered_set. There's also boost::small_vector, which we could set up with space for maybe one or two patterns?

@DHowett commented on GitHub (Jul 6, 2021): > Seem to me the number of possible pattern ids returned should be limited. Why's that? Somebody could conceivably have _many_ such IDs. Last time we saw a vector being a performance drain we switched it to an unordered_set. There's also `boost::small_vector`, which we could set up with space for maybe one or two patterns?
Author
Owner

@skyline75489 commented on GitHub (Jul 6, 2021):

Sure. I am ok with multiple pattern ids, as long as the performance drain can be fixed.

获取 Outlook for iOShttps://aka.ms/o0ukef

@skyline75489 commented on GitHub (Jul 6, 2021): Sure. I am ok with multiple pattern ids, as long as the performance drain can be fixed. 获取 Outlook for iOS<https://aka.ms/o0ukef>
Author
Owner

@skyline75489 commented on GitHub (Jul 9, 2021):

I've tried boost::small_vector, it's better but still not good:

image

I'm beginning to wonder if there's a better way to structure the code to reduce the amount of query for GetPatternId.

@skyline75489 commented on GitHub (Jul 9, 2021): I've tried `boost::small_vector`, it's better but still not good: ![image](https://user-images.githubusercontent.com/4710575/125026084-7403ae00-e0b6-11eb-8c65-16638ca308c1.png) I'm beginning to wonder if there's a better way to structure the code to reduce the amount of query for `GetPatternId`.
Author
Owner

@skyline75489 commented on GitHub (Jul 9, 2021):

On my god. I just realized this isn't about std::vector or not. In OpenConsole this call _pData->GetPatternId() is out-of-proc ?! Nope this is wrong.

I'm so confused that even I changed it to return a single integer, that call is still very expensive.

Now I get it. It's because I have Control Flow Guard (CFG) enabled, which adds additonal __guard_dispatch_icall_fptr instructions and thus increase the costs of method call. No matter what I do, as long as it's a _pData->Something(), it will be expensive.

@skyline75489 commented on GitHub (Jul 9, 2021): <del>On my god. I just realized this isn't about std::vector or not. In OpenConsole this call `_pData->GetPatternId()` is out-of-proc ?!</del> Nope this is wrong. <del>I'm so confused that even I changed it to return a single integer, that call is still very expensive.</del> Now I get it. It's because I have Control Flow Guard (CFG) enabled, which adds additonal `__guard_dispatch_icall_fptr` instructions and thus increase the costs of *method call*. No matter what I do, as long as it's a `_pData->Something()`, it will be expensive.
Author
Owner

@skyline75489 commented on GitHub (Jul 9, 2021):

Closed in favor of #10596 .

@skyline75489 commented on GitHub (Jul 9, 2021): Closed in favor of #10596 .
Author
Owner

@DHowett commented on GitHub (Jul 9, 2021):

It is worth tracking this separately, as it impacts both the dx and vt renderers. @Lhecker should write up his thoughts here

@DHowett commented on GitHub (Jul 9, 2021): It is worth tracking this separately, as it impacts both the dx and vt renderers. @Lhecker should write up his thoughts here
Author
Owner

@skyline75489 commented on GitHub (Jul 15, 2021):

Yea @DHowett is right. Even if we ignore the VT renderer part (with future refactoring work, this is possible), DX renderer still suffers from this particular issue, when the load is very heavy.

@skyline75489 commented on GitHub (Jul 15, 2021): Yea @DHowett is right. Even if we ignore the VT renderer part (with future refactoring work, this is possible), DX renderer still suffers from this particular issue, when the load is very heavy.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14403