From ac5f2e7203a9aa91682e097318ccf16d0db33abd Mon Sep 17 00:00:00 2001 From: Victor Boivie Date: Thu, 1 Jul 2021 21:42:02 +0200 Subject: [PATCH] Use flat_map/flat_set in RtpDemuxer Except for a use of std::multimap (for which there currently is no drop-in replacement), use webrtc::flat_map and flat_set for increased performance. The number of ssrcs/mids/payload types/etc is likely to be small and is generally updated very rarely, but looked up a lot. RtpDemuxer::ResolveSink's use of std::map represents about 0.6% CPU in heavily loaded media servers. It does quite a few map lookups, and by taking advantage of the increased cache locality of the flat_map and flat_set containers, performance should be increased. A previous attempt to use std::unordered_map failed in change 216243, which was reverted. This is the second attempt. Bug: webrtc:12689 Change-Id: Ifdbec63b2fd8f2f52e45ebaf12834b11dd7a41c5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/224662 Reviewed-by: Sebastian Jansson Reviewed-by: Mirko Bonadei Commit-Queue: Victor Boivie Cr-Commit-Position: refs/heads/master@{#34429} --- call/BUILD.gn | 2 ++ call/rtp_demuxer.cc | 11 +---------- call/rtp_demuxer.h | 22 ++++++++++++---------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/call/BUILD.gn b/call/BUILD.gn index 1e920b80b7..638eb0b910 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -147,6 +147,8 @@ rtc_library("rtp_receiver") { "../modules/rtp_rtcp:rtp_rtcp_format", "../rtc_base:checks", "../rtc_base:rtc_base_approved", + "../rtc_base/containers:flat_map", + "../rtc_base/containers:flat_set", ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } diff --git a/call/rtp_demuxer.cc b/call/rtp_demuxer.cc index ee96196236..28962fd2eb 100644 --- a/call/rtp_demuxer.cc +++ b/call/rtp_demuxer.cc @@ -36,16 +36,7 @@ size_t RemoveFromMultimapByValue(Container* multimap, const Value& value) { template size_t RemoveFromMapByValue(Map* map, const Value& value) { - size_t count = 0; - for (auto it = map->begin(); it != map->end();) { - if (it->second == value) { - it = map->erase(it); - ++count; - } else { - ++it; - } - } - return count; + return EraseIf(*map, [&](const auto& elem) { return elem.second == value; }); } } // namespace diff --git a/call/rtp_demuxer.h b/call/rtp_demuxer.h index b71c2bc494..fb65fce368 100644 --- a/call/rtp_demuxer.h +++ b/call/rtp_demuxer.h @@ -12,11 +12,13 @@ #define CALL_RTP_DEMUXER_H_ #include -#include #include #include #include +#include "rtc_base/containers/flat_map.h" +#include "rtc_base/containers/flat_set.h" + namespace webrtc { class RtpPacketReceived; @@ -42,10 +44,10 @@ struct RtpDemuxerCriteria { std::string rsid; // Will match packets with any of these SSRCs. - std::set ssrcs; + flat_set ssrcs; // Will match packets with any of these payload types. - std::set payload_types; + flat_set payload_types; // Return string representation of demux criteria to facilitate logging std::string ToString() const; @@ -168,24 +170,24 @@ class RtpDemuxer { // Note: Mappings are only modified by AddSink/RemoveSink (except for // SSRC mapping which receives all MID, payload type, or RSID to SSRC bindings // discovered when demuxing packets). - std::map sink_by_mid_; - std::map sink_by_ssrc_; + flat_map sink_by_mid_; + flat_map sink_by_ssrc_; std::multimap sinks_by_pt_; - std::map, RtpPacketSinkInterface*> + flat_map, RtpPacketSinkInterface*> sink_by_mid_and_rsid_; - std::map sink_by_rsid_; + flat_map sink_by_rsid_; // Tracks all the MIDs that have been identified in added criteria. Used to // determine if a packet should be dropped right away because the MID is // unknown. - std::set known_mids_; + flat_set known_mids_; // Records learned mappings of MID --> SSRC and RSID --> SSRC as packets are // received. // This is stored separately from the sink mappings because if a sink is // removed we want to still remember these associations. - std::map mid_by_ssrc_; - std::map rsid_by_ssrc_; + flat_map mid_by_ssrc_; + flat_map rsid_by_ssrc_; // Adds a binding from the SSRC to the given sink. void AddSsrcSinkBinding(uint32_t ssrc, RtpPacketSinkInterface* sink);