Skip to content

perf(SeqManager): Use std::vector rather than std::set#1807

Open
jmillan wants to merge 5 commits into
v3from
perf-seqmanager
Open

perf(SeqManager): Use std::vector rather than std::set#1807
jmillan wants to merge 5 commits into
v3from
perf-seqmanager

Conversation

@jmillan
Copy link
Copy Markdown
Member

@jmillan jmillan commented May 22, 2026

It increases performance greatly[*] thanks to the cache locality of the vector.

Scenarios where this is noticeable is when there are SeqManager drops due to, ie: Codec implementation or SimulcastConsumer dropping a packet.

[*]: Using mediasoup-demo with 1 audio|video producer and 100 audio|video consumers the CPU usage of SeqManager went down from >10% to <2%

jmillan added 2 commits May 22, 2026 15:27
It increases performance greatly[*] thanks to the cache locality of the vector.

Scenarios where this is noticeable is when there are SeqManager drops due to,
ie: Codec implementation or SimulcastConsumer dropping a packet.

[*]: Using mediasoup-demo 1 audio|video producer and 100 audio|video consumers the CPU
usage of SeqManager went of from >10% to <2%
Comment thread worker/include/RTC/SeqManager.hpp Outdated
Comment thread worker/src/RTC/SeqManager.cpp Outdated
Comment thread worker/src/RTC/SeqManager.cpp Outdated
Comment thread worker/src/RTC/SeqManager.cpp
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

Comment thread worker/src/RTC/SeqManager.cpp Outdated
Comment thread worker/src/RTC/SeqManager.cpp Outdated
Comment thread CHANGELOG.md Outdated
Co-authored-by: Iñaki Baz Castillo <ibc@aliax.net>
@penguinol
Copy link
Copy Markdown
Contributor

penguinol commented May 23, 2026

Not sure whether this works properly in all situations.
It seems std::binary_search and std::lower_bound have different requirement to compare function.
https://www.cppreference.com/cpp/algorithm/lower_bound

Unlike std::binary_search, std::lower_bound does not require operator< or comp to be asymmetric (i.e., a < b and b < a always have different results). In fact, it does not even require value < *iter or comp(value, *iter) to be well-formed for any iterator iter in [first, last).

https://en.cppreference.com/cpp/named_req/Compare

Maybe realted to #1370

@ibc
Copy link
Copy Markdown
Member

ibc commented May 23, 2026

@jmillan
Copy link
Copy Markdown
Member Author

jmillan commented May 23, 2026

What about if we used the new Utils::UnwrappedSequenceNumber class that I borrowed from libwebrtc/dcsctp?

That is totally unrelated to this PR. Here I'm just using a more efficient container for the job after measuring the performance.

I believe there is an open issue with your suggestion which is another different topic than this one.

@jmillan
Copy link
Copy Markdown
Member Author

jmillan commented May 23, 2026

Not sure whether this works properly in all situations.
It seems std::binary_search and std::lower_bound have different requirement to compare function.
https://www.cppreference.com/cpp/algorithm/lower_bound

Unlike std::binary_search, std::lower_bound does not require operator< or comp to be asymmetric (i.e., a < b and b < a always have different results). In fact, it does not even require value < *iter or comp(value, *iter) to be well-formed for any iterator iter in [first, last).

https://en.cppreference.com/cpp/named_req/Compare

Maybe realted to #1370

Thanks, I'll check this info.

@jmillan
Copy link
Copy Markdown
Member Author

jmillan commented May 25, 2026

Unlike std::binary_search, std::lower_bound does not require operator< or comp to be asymmetric (i.e., a < b and b < a always have different results). In fact, it does not even require value < *iter or comp(value, *iter) to be well-formed for any iterator iter in [first, last).

This this no trouble. In our case if a<b b>a, so I don't see any problem. Besides, al tests pass. Do you see a specific issue that is not present in current v3?

@penguinol
Copy link
Copy Markdown
Contributor

penguinol commented May 25, 2026

std::set uses a red-black tree while std::vector uses binary search, so they use different algorithms.
I am concerned about whether they behave the same with SeqLowerThan, which does not satisfy the C++ Compare standard.

@jmillan
Copy link
Copy Markdown
Member Author

jmillan commented May 25, 2026

std::set uses a red-black tree while std::vector uses binary search, so they use different algorithms.
I am concerned about whether they behave the same with SeqLowerThan, which does not satisfy the C++ Compare standard.

We've plenty of tests, all passing: https://github.com/versatica/mediasoup/blob/v3/worker/test/src/RTC/TestSeqManager.cpp#L1

Both use the same comp. The difference is that binary_search requires it to be asymmetric (i.e., a < b and b < a always have different results), which is the case of SeqLowerThan anyways.

Any specific failing case/test on top of your mind?

@jmillan
Copy link
Copy Markdown
Member Author

jmillan commented May 25, 2026

Ok, so IsLowerThan not strictly asymmetric: for some values, both IsLowerThan(a, b) and IsLowerThan(b, a) can be false (e.g., when a == b or when the difference is exactly half the range).

I'll avoid the binary_search.

@jmillan
Copy link
Copy Markdown
Member Author

jmillan commented May 25, 2026

@penguinol please check the latest commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants