From 4970f026256b46e8fe8d3a21ae1ec4b2542040a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Fri, 22 May 2026 15:09:56 +0200 Subject: [PATCH 1/5] perf(SeqManager): Use std::vector rather than std::set 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% --- worker/include/RTC/SeqManager.hpp | 7 ++-- worker/src/RTC/SeqManager.cpp | 53 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/worker/include/RTC/SeqManager.hpp b/worker/include/RTC/SeqManager.hpp index f15d4a5949..89623e8f91 100644 --- a/worker/include/RTC/SeqManager.hpp +++ b/worker/include/RTC/SeqManager.hpp @@ -2,8 +2,9 @@ #define RTC_SEQ_MANAGER_HPP #include "common.hpp" -#include // std::numeric_limits -#include +#include // for lower_bound, binary_search, distance, find_if +#include // std::numeric_limits +#include namespace RTC { @@ -53,7 +54,7 @@ namespace RTC T maxInput{ 0 }; T maxDropped{ 0 }; T maxForwarded{ 0 }; - std::set dropped; + std::vector dropped; }; } // namespace RTC diff --git a/worker/src/RTC/SeqManager.cpp b/worker/src/RTC/SeqManager.cpp index 75591a9bb6..c92679383d 100644 --- a/worker/src/RTC/SeqManager.cpp +++ b/worker/src/RTC/SeqManager.cpp @@ -63,9 +63,13 @@ namespace RTC { this->maxInput = input; this->maxDropped = input; - // Insert input in the last position. - // Explicitly insert at the end, which is more performant. - this->dropped.insert(this->dropped.end(), input); + // Insert input in sorted order, if not present. + SeqLowerThan seqLowerThan; + auto it = std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + if (it == this->dropped.end() || *it != input) + { + this->dropped.insert(it, input); + } ClearDropped(); } @@ -74,7 +78,13 @@ namespace RTC // Allows for properly accounting for out of order drops until an input is forwarded. else if (this->maxInput == this->maxDropped && SeqManager::IsSeqHigherThan(input, this->maxForwarded)) { - this->dropped.insert(input); + // Insert input in sorted order, if not present. + SeqLowerThan seqLowerThan; + auto it = std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + if (it == this->dropped.end() || *it != input) + { + this->dropped.insert(it, input); + } ClearDropped(); } @@ -113,7 +123,7 @@ namespace RTC goto done; } // This input was dropped. - else if (this->dropped.find(input) != this->dropped.end()) + else if (std::binary_search(this->dropped.begin(), this->dropped.end(), input, SeqLowerThan())) { MS_DEBUG_DEV("trying to send a dropped input"); @@ -122,12 +132,10 @@ namespace RTC // There are dropped inputs, calculate 'base' for this input. else { - auto droppedCount = this->dropped.size(); - - // Get the first dropped input which is higher than or equal 'input'. - auto it = this->dropped.lower_bound(input); - - droppedCount -= std::distance(it, this->dropped.end()); + // Count dropped numbers less than input. + auto droppedCount = std::distance( + this->dropped.begin(), + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, SeqLowerThan())); base = (this->base - droppedCount) & SeqManager::MaxValue; } @@ -191,19 +199,16 @@ namespace RTC const size_t previousDroppedSize = this->dropped.size(); - for (auto it = this->dropped.begin(); it != this->dropped.end();) - { - auto value = *it; - - if (SeqManager::IsSeqHigherThan(value, this->maxInput)) - { - it = this->dropped.erase(it); - } - else - { - break; - } - } + // Cleanup dropped values. + this->dropped.erase( + this->dropped.begin(), + std::find_if( + this->dropped.begin(), + this->dropped.end(), + [this](T value) + { + return !SeqManager::IsSeqHigherThan(value, this->maxInput); + })); // Adapt base. this->base = (this->base - (previousDroppedSize - this->dropped.size())) & SeqManager::MaxValue; From fc07b638df93f92f2a14e4f77f451ec960325035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Fri, 22 May 2026 15:31:35 +0200 Subject: [PATCH 2/5] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ee22cc4dc..45f20c1d3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### NEXT - Node: Update TypeScript to v6 ([PR #1790](https://github.com/versatica/mediasoup/pull/1790)). +- Worker: SeqManager, use std::vector rather than std::set ([1807](https://github.com/versatica/mediasoup/pull/1807)). ### 3.19.22 From b33bd0e07a4f30c65357c5d888a30b5e5a6c4a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Fri, 22 May 2026 15:42:58 +0200 Subject: [PATCH 3/5] handle feedback --- worker/include/RTC/SeqManager.hpp | 3 +-- worker/src/RTC/SeqManager.cpp | 15 ++++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/worker/include/RTC/SeqManager.hpp b/worker/include/RTC/SeqManager.hpp index 89623e8f91..084ef79761 100644 --- a/worker/include/RTC/SeqManager.hpp +++ b/worker/include/RTC/SeqManager.hpp @@ -2,8 +2,7 @@ #define RTC_SEQ_MANAGER_HPP #include "common.hpp" -#include // for lower_bound, binary_search, distance, find_if -#include // std::numeric_limits +#include // std::numeric_limits #include namespace RTC diff --git a/worker/src/RTC/SeqManager.cpp b/worker/src/RTC/SeqManager.cpp index c92679383d..d413853913 100644 --- a/worker/src/RTC/SeqManager.cpp +++ b/worker/src/RTC/SeqManager.cpp @@ -64,8 +64,10 @@ namespace RTC this->maxInput = input; this->maxDropped = input; // Insert input in sorted order, if not present. - SeqLowerThan seqLowerThan; - auto it = std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + const SeqLowerThan seqLowerThan; + const auto it = + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + if (it == this->dropped.end() || *it != input) { this->dropped.insert(it, input); @@ -79,8 +81,10 @@ namespace RTC else if (this->maxInput == this->maxDropped && SeqManager::IsSeqHigherThan(input, this->maxForwarded)) { // Insert input in sorted order, if not present. - SeqLowerThan seqLowerThan; - auto it = std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + const SeqLowerThan seqLowerThan; + const auto it = + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + if (it == this->dropped.end() || *it != input) { this->dropped.insert(it, input); @@ -133,9 +137,10 @@ namespace RTC else { // Count dropped numbers less than input. - auto droppedCount = std::distance( + const auto droppedCount = std::distance( this->dropped.begin(), std::lower_bound(this->dropped.begin(), this->dropped.end(), input, SeqLowerThan())); + base = (this->base - droppedCount) & SeqManager::MaxValue; } From 12380a76d66d941c8444746551ca47db5ad99749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Fri, 22 May 2026 17:35:02 +0200 Subject: [PATCH 4/5] Update CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: IƱaki Baz Castillo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f20c1d3b..f712ae4f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ### NEXT - Node: Update TypeScript to v6 ([PR #1790](https://github.com/versatica/mediasoup/pull/1790)). -- Worker: SeqManager, use std::vector rather than std::set ([1807](https://github.com/versatica/mediasoup/pull/1807)). +- Worker: `SeqManager`, use `std::vector` rather than `std::set` ([1807](https://github.com/versatica/mediasoup/pull/1807)). ### 3.19.22 From 8a204f02bb49e2772a70b9ed911b5af3948d8a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Mon, 25 May 2026 10:24:48 +0200 Subject: [PATCH 5/5] avoid using binary_search --- worker/src/RTC/SeqManager.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/worker/src/RTC/SeqManager.cpp b/worker/src/RTC/SeqManager.cpp index d413853913..41d98fdbb7 100644 --- a/worker/src/RTC/SeqManager.cpp +++ b/worker/src/RTC/SeqManager.cpp @@ -126,18 +126,21 @@ namespace RTC { goto done; } - // This input was dropped. - else if (std::binary_search(this->dropped.begin(), this->dropped.end(), input, SeqLowerThan())) - { - MS_DEBUG_DEV("trying to send a dropped input"); - - return false; - } - // There are dropped inputs, calculate 'base' for this input. else { - // Count dropped numbers less than input. - const auto droppedCount = std::distance( + const SeqLowerThan seqLowerThan; + const auto it = + std::lower_bound(this->dropped.begin(), this->dropped.end(), input, seqLowerThan); + + if (it != this->dropped.end() && !seqLowerThan(input, *it) && !seqLowerThan(*it, input)) + { + MS_DEBUG_DEV("trying to send a dropped input"); + + return false; + } + + // There are dropped inputs, calculate 'base' for this input. + auto droppedCount = std::distance( this->dropped.begin(), std::lower_bound(this->dropped.begin(), this->dropped.end(), input, SeqLowerThan()));