C++23 新增扁平化關聯容器詳解

文章目錄

    • 一、引言
      • 已有關聯容器回顧
      • 新容器的引入原因
    • 二、`std::flat_set`
      • 定義與特性
      • 代碼示例
      • 適用場景
    • 三、`std::flat_multiset`
      • 定義與特性
      • 代碼示例
      • 適用場景
    • 四、`std::flat_map`
      • 定義與特性
      • 代碼示例
      • 適用場景
    • 五、`std::flat_multimap`
      • 定義與特性
      • 代碼示例
      • 適用場景
    • 六、與其他容器的比較
      • 與 `std::set` 和 `std::multiset` 的比較
      • 與 `std::map` 和 `std::multimap` 的比較
    • 七、總結

一、引言

在 C++23 標準中,引入了四個新的關聯容器:std::flat_setstd::flat_multisetstd::flat_mapstd::flat_multimap。這些容器是對底層有序隨機訪問容器進行包裝的容器適配器,旨在為開發者提供在某些場景下比傳統關聯容器更高效的選擇。在介紹這四個新容器之前,我們先回顧一下 C++ 中已有的關聯容器。

已有關聯容器回顧

  • C++98:引入了 std::mapstd::setstd::multimapstd::multiset,這些容器基于紅黑樹實現,元素按鍵有序存儲,插入、刪除和查找操作的時間復雜度為 O ( l o g n ) O(log n) O(logn)
  • C++11:引入了 std::unordered_mapstd::unordered_setstd::unordered_multimapstd::unordered_multiset,這些容器基于哈希表實現,元素無序存儲,平均情況下插入、刪除和查找操作的時間復雜度為 O ( 1 ) O(1) O(1)

新容器的引入原因

新容器的引入主要是為了在內存消耗和性能方面提供不同的選擇。與傳統的關聯容器相比,平鋪容器在某些場景下具有更好的緩存局部性,從而提高性能。

二、std::flat_set

定義與特性

std::flat_set 是一個類似于 std::set 的容器,但它使用扁平化存儲的唯一鍵集合。它的底層實現使用排序的連續存儲(通常是 std::vector 或類似結構),而不是樹結構。這使得元素在內存中是連續存儲的,具有以下特點:

  • 查找速度快:查找操作使用二分查找,時間復雜度為 O ( l o g n ) O(log n) O(logn)。由于內存連續,緩存命中率高,總體查找速度比 std::set 快。
  • 插入和刪除較慢:插入和刪除操作通常需要對數組中的元素進行整體移動,尤其在不支持移動構造時,時間復雜度為 O ( n ) O(n) O(n)
  • 迭代速度快:由于內存局部性,迭代速度比 std::set 快。
  • 內存占用小:相對于平衡二叉樹,減少了節點指針的維護,從而節省了內存空間。

代碼示例

#include <flat_set>
#include <iostream>int main() {std::flat_set<int> primes{2, 3, 5, 7, 11};// 插入元素primes.insert(13);// 檢查存在性if (primes.contains(7)) {std::cout << "7 is a prime number" << std::endl;}// 范圍查詢auto [begin, end] = primes.equal_range(5);for (auto it = begin; it != end; ++it) {std::cout << *it << " ";}std::cout << std::endl;return 0;
}

適用場景

  • 需要頻繁查找但較少插入/刪除:由于查找速度快,插入和刪除操作相對較慢,適合用于需要頻繁查找元素的場景。
  • 需要快速迭代:內存連續的特性使得迭代速度快,適合需要快速遍歷元素的場景。
  • 內存受限環境:內存占用小的特點使得它在內存受限的環境中更具優勢。

三、std::flat_multiset

定義與特性

std::flat_multiset 類似于 std::flat_set,但允許存儲多個具有相同鍵的元素。它同樣使用排序的連續存儲,具有與 std::flat_set 類似的性能特點:

  • 查找速度快:查找操作使用二分查找,時間復雜度為 O ( l o g n ) O(log n) O(logn)
  • 插入和刪除較慢:插入和刪除操作通常需要對數組中的元素進行整體移動,時間復雜度為 O ( n ) O(n) O(n)
  • 迭代速度快:由于內存局部性,迭代速度快。
  • 內存占用小:相對于平衡二叉樹,減少了節點指針的維護,從而節省了內存空間。

代碼示例

#include <flat_set>
#include <iostream>int main() {std::flat_multiset<int> numbers{1, 2, 2, 3, 3, 3};// 插入元素numbers.insert(4);// 查找元素auto range = numbers.equal_range(2);for (auto it = range.first; it != range.second; ++it) {std::cout << *it << " ";}std::cout << std::endl;return 0;
}

適用場景

  • 需要存儲重復元素且需要快速查找:與 std::flat_set 類似,但允許存儲重復元素,適合需要存儲重復元素且需要快速查找的場景。
  • 需要快速迭代:內存連續的特性使得迭代速度快,適合需要快速遍歷元素的場景。
  • 內存受限環境:內存占用小的特點使得它在內存受限的環境中更具優勢。

四、std::flat_map

定義與特性

std::flat_map 是一個類似于 std::map 的容器,但它使用扁平化存儲的鍵值對容器。它的底層實現使用兩個有序數組,一個存儲鍵,另一個存儲值,具有以下特點:

  • 查找速度快:查找操作使用二分查找,時間復雜度為 O ( l o g n ) O(log n) O(logn)。由于內存連續,緩存命中率高,總體查找速度比 std::map 快。
  • 插入和刪除較慢:插入和刪除操作通常需要對數組中的元素進行整體移動,尤其在不支持移動構造時,時間復雜度為 O ( n ) O(n) O(n)
  • 迭代速度快:由于內存局部性,迭代速度比 std::map 快。
  • 內存占用小:相對于平衡二叉樹,減少了節點指針的維護,從而節省了內存空間。
  • 使用隨機訪問迭代器:與 std::map 使用雙向迭代器不同,std::flat_map 使用隨機訪問迭代器。
  • 迭代器不穩定:插入和刪除元素時迭代器會失效。
  • 無法存儲不可復制和不可移動的值類型:由于需要對元素進行移動和復制,無法存儲不可復制和不可移動的值類型。
  • 異常安全性弱:在刪除和插入時移動值可能會拋出異常。

代碼示例

#include <flat_map>
#include <iostream>
#include <string>int main() {std::flat_map<std::string, int> ages{{"Alice", 30},{"Bob", 25},{"Charlie", 35}};// 插入元素(可能觸發排序和移動)ages.insert({"David", 28});// 查找元素if (auto it = ages.find("Alice"); it != ages.end()) {std::cout << "Alice is " << it->second << " years old" << std::endl;}// 迭代for (const auto& [name, age] : ages) {std::cout << name << ": " << age << std::endl;}return 0;
}

適用場景

  • 需要頻繁查找但較少插入/刪除:由于查找速度快,插入和刪除操作相對較慢,適合用于需要頻繁查找元素的場景。
  • 需要快速迭代:內存連續的特性使得迭代速度快,適合需要快速遍歷元素的場景。
  • 內存受限環境:內存占用小的特點使得它在內存受限的環境中更具優勢。

五、std::flat_multimap

定義與特性

std::flat_multimap 類似于 std::flat_map,但允許存儲多個具有相同鍵的鍵值對。它同樣使用排序的連續存儲,具有與 std::flat_map 類似的性能特點:

  • 查找速度快:查找操作使用二分查找,時間復雜度為 O ( l o g n ) O(log n) O(logn)
  • 插入和刪除較慢:插入和刪除操作通常需要對數組中的元素進行整體移動,時間復雜度為 O ( n ) O(n) O(n)
  • 迭代速度快:由于內存局部性,迭代速度快。
  • 內存占用小:相對于平衡二叉樹,減少了節點指針的維護,從而節省了內存空間。

代碼示例

#include <flat_map>
#include <iostream>
#include <string>int main() {std::flat_multimap<std::string, int> scores{{"Alice", 80},{"Bob", 90},{"Alice", 85}};// 插入元素scores.insert({"Charlie", 75});// 查找元素auto range = scores.equal_range("Alice");for (auto it = range.first; it != range.second; ++it) {std::cout << it->first << ": " << it->second << std::endl;}return 0;
}

適用場景

  • 需要存儲重復鍵的鍵值對且需要快速查找:與 std::flat_map 類似,但允許存儲重復鍵的鍵值對,適合需要存儲重復鍵的鍵值對且需要快速查找的場景。
  • 需要快速迭代:內存連續的特性使得迭代速度快,適合需要快速遍歷元素的場景。
  • 內存受限環境:內存占用小的特點使得它在內存受限的環境中更具優勢。

六、與其他容器的比較

std::setstd::multiset 的比較

特性std::set/std::multisetstd::flat_set/std::flat_multiset
底層實現紅黑樹排序的連續存儲(通常是 std::vector
查找速度 O ( l o g n ) O(log n) O(logn) O ( l o g n ) O(log n) O(logn),但緩存友好,總體速度更快
插入和刪除速度 O ( l o g n ) O(log n) O(logn) O ( n ) O(n) O(n)
迭代速度較慢較快
內存占用較大較小
迭代器穩定性穩定不穩定

std::mapstd::multimap 的比較

特性std::map/std::multimapstd::flat_map/std::flat_multimap
底層實現紅黑樹排序的連續存儲(通常是 std::vector
查找速度 O ( l o g n ) O(log n) O(logn) O ( l o g n ) O(log n) O(logn),但緩存友好,總體速度更快
插入和刪除速度 O ( l o g n ) O(log n) O(logn) O ( n ) O(n) O(n)
迭代速度較慢較快
內存占用較大較小
迭代器穩定性穩定不穩定
迭代器類型雙向迭代器隨機訪問迭代器

七、總結

C++23 引入的 std::flat_setstd::flat_multisetstd::flat_mapstd::flat_multimap 為開發者提供了在某些場景下比傳統關聯容器更高效的選擇。這些容器在查找和迭代操作上具有更好的性能,同時內存占用更小。然而,它們的插入和刪除操作相對較慢,迭代器也不穩定。因此,在選擇使用這些容器時,需要根據具體的應用場景進行權衡。如果需要頻繁進行查找和迭代操作,且插入和刪除操作較少,那么這些平鋪容器是一個不錯的選擇。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81953.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81953.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81953.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用zap,對web應用/API接口 做安全檢測

https://www.zaproxy.org/getting-started/ 檢測方法 docker pull ghcr.io/zaproxy/zaproxy:stable# 執行baseline測試 docker run -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \ -t https://baseline.yeshen.org# 執行api測試 docker run -t ghcr.io/zaproxy/zaproxy…

Qt—模態與非模態對話框

Qt—模態與非模態對話框 核心概念 ?模態對話框??&#xff1a;強制用戶優先處理當前窗口&#xff0c;阻塞指定范圍的用戶交互。?非模態對話框??&#xff1a;允許用戶自由切換窗口&#xff0c;無交互限制。 一、模態對話框類型與行為 1. 應用級模態&#xff08;Applica…

Axure高保真CRM客戶關系管理系統原型

一套出色的CRM&#xff08;客戶關系管理&#xff09;系統&#xff0c;無疑是企業管理者掌控客戶動態、提升銷售業績的得力助手。今天&#xff0c;就為大家介紹一款精心打造的Axure高保真CRM客戶關系管理系統原型模板&#xff0c;助你輕松開啟高效客戶管理之旅。 這款CRM原型模…

【羊圈——狀壓 + DP / 記憶化搜索DP】

題目 一般DP代碼&#xff08;注意&#xff0c;這里只能向外推(起始狀態是f(1,0)&#xff0c;不能向內推&#xff08;不然會導致之前的羊圈被割裂&#xff09;&#xff09; #include <bits/stdc.h> using namespace std;const int MAX_N 210; const int MAX_M 16;int n…

講解Mysql InnoDB的MVCC

1. 定義 MVCC是多版本并發控制&#xff08;Multi - Version Concurrency Control&#xff09;的縮寫。它是InnoDB存儲引擎實現高并發控制的一種機制。在數據庫系統中&#xff0c;多個事務可能會同時對數據進行讀寫操作&#xff0c;而MVCC通過為數據行保存多個版本來解決并發事務…

ZeroMQ Sockets介紹及應用示例

1. 概念解釋 ZeroMQ Sockets提供了一種類標準套接字&#xff08;socket-like&#xff09;的 API&#xff0c;是消息導向的通信機制&#xff0c;基于 TCP/UDP 等傳輸層協議&#xff0c;但封裝了底層細節&#xff08;如連接管理、消息路由、緩沖區等&#xff09;&#xff0c;提供…

語音合成之十五 語音合成(TTS)分句生成拼接時的響度一致性問題:現狀、成因與對策

語音合成&#xff08;TTS&#xff09;分句生成拼接時的響度一致性問題&#xff1a;現狀、成因與對策 引言&#xff1a;分段式文本轉語音中的響度一致性挑戰業界對響度差異問題的認知拼接語音片段中響度變化的根本原因分段拼接的固有挑戰各片段預測韻律特征的差異文本特征和模型…

Android中Binder驅動作用?

Binder驅動的作用與核心功能 Binder驅動是Android系統中實現進程間通信&#xff08;IPC&#xff09;的核心底層組件&#xff0c;它工作于Linux內核層&#xff0c;負責管理跨進程通信的建立、數據傳輸、資源同步等關鍵任務。以下是其核心作用及實現細節&#xff1a; 1. ??進程…

網絡學習-TCP協議(七)

一、TCP協議 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。 1、三次握手 客戶端&#xff1a; 1、先發起連接&#xff0c;發送SYN置1&#xff0c;seqnum12345(隨機值)----半連接…

【Python 基礎與實戰】從基礎語法到項目應用的全流程解析

&#xff08;1&#xff09;列表和元組的區別是什么?如何從列表創建元組?如何從元組創建列表? 列表和元組的區別&#xff1a; 可變性&#xff1a;列表是可變的&#xff0c;即可以對列表進行元素的增、刪、改操作。例如&#xff0c;可以使用append()方法添加元素&#xff0c;r…

Docker部署Zookeeper集群

簡介 ZooKeeper 是一個開源的分布式協調服務&#xff0c;由 Apache 軟件基金會開發和維護。它主要用于管理和協調分布式系統中的多個節點&#xff0c;以解決分布式環境下的常見問題&#xff0c;如配置管理、服務發現、分布式鎖等。ZooKeeper 提供了一種可靠的機制&#xff0c;…

【學習筆記】Sophus (Python) 使用文檔

以下是一份針對 Sophus 庫的 Python 使用文檔&#xff0c;涵蓋基礎概念、安裝方法、核心功能及代碼示例。內容圍繞 SO3&#xff08;3D旋轉群&#xff09;和 SE3&#xff08;3D剛體變換群&#xff09;展開&#xff0c;適合機器人學、SLAM、三維幾何等領域。 Sophus (Python) 使用…

計算機圖形學:(三)MVP變換擴展

Three.js WebGL允許把JavaScript和OpenGL 結合在一起運用&#xff0c;但使用WebGL原生的API來寫3D程序非常的復雜&#xff0c;同時需要相對較多的數學知識&#xff0c;對于前端開發者來說學習成本非常高。 Three.js是基于webGL的封裝的一個易于使用且輕量級的3D庫&#xff0c;T…

MySQL數據庫操作合集

一、SQL通用語法 ①SQL語句可以單行或多行書寫&#xff0c;以分號結尾。 ②SQL語句可以使用空格/縮進來增強語句可讀性。 ③MySQL數據庫的SQL語句不區分大小寫&#xff0c;關鍵字建議使用大寫。 ④注釋&#xff1a; 單行注釋&#xff1a; -- 注釋內容 或 # 注釋內容&#…

傳統工程項目管理與業財一體化管理的區別?

在工程項目管理領域&#xff0c;傳統管理模式與新興的業財一體化管理模式正在形成鮮明對比。隨著數字化轉型的加速&#xff0c;工程行業對高效、透明、協同的管理需求日益迫切。傳統工程項目管理依賴人工操作、分散系統和分模塊管理&#xff0c;難以應對復雜項目的全生命周期需…

敦煌網測評從環境搭建到風控應對,精細化運營打造安全測評體系

自養號測評&#xff0c;搶占流量為快速提升產品權重和銷量&#xff0c;很多賣家常采用自己養號補單測評的方式&#xff0c;技術搭建需要很多要素 一、硬件參數的關聯性 在我們使用設備進行注冊或操作賬號的過程中&#xff0c;系統會記錄下大量的系統與網絡參數&#xff0c;其中…

redis Pub/Sub 簡介 -16 (PUBLISH、SUBSCRIBE、PSUBSCRIBE)

Redis Pub/Sub 簡介&#xff1a;PUBLISH、SUBSCRIBE、PSUBSCRIBE Redis Pub/Sub 是一種強大的消息傳遞范例&#xff0c;可在應用程序的不同部分之間實現實時通信。它是構建可擴展和響應式系統的基石&#xff0c;允許組件在沒有直接依賴的情況下進行交互。本章將全面介紹 Redis…

JavaSE核心知識點03高級特性03-01(集合框架)

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 JavaSE核心知識點03高級特性03-01&#xff0…

日志分析-IIS日志分析

環境準備 https://xj.edisec.net/challenges/115 題目要求 windows系統中才有的IIS服務 既然是windows平臺&#xff0c;當然需要rdp登錄&#xff0c;在ssh登錄失敗 解題過程 phpstudy--2018站點日志.(.log文件)所在路徑&#xff0c;提供絕對路徑 Windows服務的日志一般有固定…

一、web安全基礎入門

1、Windows命令 文件和目錄操作 dir&#xff1a;列出當前目錄下的文件和子目錄。cd&#xff1a;切換目錄&#xff0c;例如 cd C:\Users 切換到C盤的Users目錄。md 或 mkdir&#xff1a;創建新目錄&#xff0c;如 md testdir。rd 或 rmdir&#xff1a;刪除空目錄&#xff0c;例…