0

0

c++23的std::flat_map相比std::map快在哪里? (缓存友好性分析)

尼克

尼克

发布时间:2026-01-12 13:19:23

|

845人浏览过

|

来源于php中文网

原创

std::flat_map查找更快因其底层用连续vector存储已排序pair,利于CPU缓存预取;插入删除慢因需移动后续元素(O(n)),而map仅改指针(O(log n))。

c++23的std::flat_map相比std::map快在哪里? (缓存友好性分析)

为什么 std::flat_map 查找更快?——底层是连续内存

因为 std::flat_map 底层用 std::vector 存储已排序的 std::pair,所有元素在内存中紧挨着;而 std::map 是红黑树,节点动态分配、分散在堆上。CPU 预取器能高效加载相邻缓存行,std::flat_map 的二分查找(std::lower_bound)每次比较都大概率命中 L1/L2 缓存;std::map 每次跳转都可能触发一次缓存未命中,甚至缺页。

std::flat_map 的插入/删除为什么慢?——不是所有操作都受益

插入或删除任意位置时,std::flat_map 要移动后续所有元素(O(n) 时间 + 大量内存拷贝),而 std::map 仅修改指针(O(log n))。尤其当键值类型较大(如 std::string 或自定义结构体)时,移动开销剧增。它只适合「读多写少」且数据规模适中(通常

  • 插入新元素必须保持有序 → 找到位置后,调用 std::vector::insert(),触发尾部元素批量后移
  • 删除元素同理 → std::vector::erase() 引发后续元素前移
  • 若频繁修改,std::flat_map::reserve() 可减少重分配,但无法避免移动本身

迭代器失效规则完全不同——别混用习惯

std::flat_map 迭代器在插入/删除时**全部失效**(因为底层 std::vector 可能重新分配或移动内存);而 std::map 迭代器仅在被删节点上失效,其余稳定。这意味着:如果你在循环中边遍历边 erase()std::flat_map 必须改用索引或 remove_if + erase 惯用法,不能直接 it = m.erase(it)

auto it = fm.begin();
while (it != fm.end()) {
    if (should_remove(it->first)) {
        it = fm.erase(it); // ❌ 编译失败:std::flat_map::erase 返回 void
    } else {
        ++it;
    }
}

正确写法是:

立即学习C++免费学习笔记(深入)”;

TapNow
TapNow

新一代AI视觉创作引擎

下载
fm.erase(
    std::remove_if(fm.begin(), fm.end(),
        [](const auto& p) { return should_remove(p.first); }),
    fm.end()
);

缓存友好性有代价——空间与局部性权衡

std::flat_map 内存占用略小(无树节点指针开销),但缺乏「局部性分级」:整个容器要么全在缓存里,要么大量缺失;而 std::map 虽然单次访问慢,但热节点(如高频查询的父路径)可能长期驻留缓存。另外,std::flat_map 不支持原地修改 value(operator[]at() 返回 const 引用),必须用 insert_or_assign 或先查再赋值——这又引入一次二分查找。

真正关键的不是“快”,而是「你是否在反复查询同一片小数据集」。如果数据集大、更新勤、或 key 分布稀疏,连续布局反而让 CPU 预取失效——这时候 flat 就成了负优化。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

187

2025.07.04

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

386

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

569

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

74

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

28

2025.11.16

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

4

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号