C++ 实现海量数据去重 Bitmap 算法及其空间开销优化与查找提升逻辑【源码】

老婷吖_9796

老婷吖_9796

2026-05-27

974人浏览

原创

Bitmap不能直接用std::vector去重,因其底层按位存储但接口伪装值语义,不支持取地址、指针算术及批量位操作;应手动管理uint64_t*内存,配合离散化、分桶或布隆过滤器应对稀疏与超大值域,并用std::atomic保障并发安全。

c++ 实现海量数据去重 bitmap 算法及其空间开销优化与查找提升逻辑【源码】

Bitmap 为什么不能直接用 std::vector 做去重

因为 std::vector 是特化容器,底层按位存储但接口伪装成“值语义”,导致无法直接取地址、不支持指针算术、迭代器行为异常;更关键的是它不提供原始内存视图,无法做批量位操作(如 SIMD 或字级并行置位),在海量数据场景下反而拖慢性能。真正做 Bitmap 去重,得自己管理 uint64_t* 或 unsigned char* 内存块。

实操建议:

  • 用 std::unique_ptr 管理内存,长度按 (max_value + 63) / 64 计算,确保覆盖所有可能值
  • 避免用 std::bitset —— 它大小编译期固定,不适用于运行时决定数据范围的海量场景
  • 如果值域稀疏(比如只出现 0~100 万中的 10 万个数),先做离散化映射到紧凑索引,再建 Bitmap,否则空间浪费严重

如何安全处理超大值域(>2^32)而不爆内存

当输入数据最大值达到百亿(1e10)甚至千亿,直接分配 1e10 / 8 ≈ 1.25 GB 内存只是理论下限,实际还受对齐、页表、碎片影响;更现实的做法是分桶(bucketed bitmap)或布隆过滤器预筛+二级精确 Bitmap。

推荐折中方案:

  • 按高 16 位分桶:用 std::unordered_map>,每个桶管 65536 个连续整数区间
  • 插入时先算 bucket_id = value >> 16,再算桶内偏移 bit_offset = value & 0xFFFF
  • 只对实际出现过 bucket_id 的桶分配内存,空桶不占空间 —— 对稀疏数据极友好
  • 注意:此结构查找时间仍是 O(1),但常数略高;若需极致查询速度,可配合 std::array<:unique_ptr>, 65536>(静态桶),但要求编译期知道最大 bucket 数

set_bit() 和 test_bit() 的原子性与并发安全边界

单线程下位操作只需普通读写;但多线程写同一 Bitmap 时,set_bit() 不是原子的 —— 它要先读字、改位、再写回字,中间可能被其他线程覆盖。即使用了 std::atomic 数组,仍需保证整个“读-改-写”流程原子,否则丢数据。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

正确做法:

  • 对每个 uint64_t 元素用 std::atomic 存储,set_bit() 改用 fetch_or():
void set_bit(size_t pos) {
    size_t word_idx = pos / 64;
    size_t bit_idx = pos % 64;
    uint64_t mask = 1ULL 
  • 不要用 load() + modify + store() 手动实现,这是竞态温床
  • 如果只是读多写少,且允许短暂重复(如日志去重),可用 std::memory_order_acquire/release 降级同步开销;但严格去重要求无丢失,必须用 fetch_or 类 CAS 操作
  • 查找提升:如何让 next_set_bit(pos) 快 10 倍

    遍历 Bitmap 查下一个已置位位置,朴素循环检查每个 bit 效率极低。现代 CPU 提供 __builtin_ctzll()(GCC/Clang)或 _tzcnt_u64()(MSVC)找末尾零位数,配合 word & -word 提取最低位,可做到“一个字内查位 O(1)”。

    优化逻辑:

    • 先跳过全零字:while (word == 0) { word_idx++; word = words_[word_idx].load(); }
    • 对非零字,用 uint64_t lowest = word & -word; 得到最低置位掩码,再用 __builtin_ctzll(lowest) 得 bit 偏移
    • 每次清除最低位:word &= word - 1;,直到该字清空,再进下一字
    • 注意:Windows 上 _tzcnt_u64 在 AMD CPU 上快,在 Intel 上等价于 _bsf_u64,但 GCC 的 __builtin_ctzll 会自动编译为最优指令

    这个技巧在做“找出所有去重后数字”或“位图交集扫描”时,能把遍历耗时从毫秒级压到百微秒级 —— 但前提是数据局部性好(连续置位多),否则缓存不友好反拖慢。

    C++免费学习笔记(深入):立即使用
    在学习笔记中,你将探索 C++ 的入门与实战技巧!

    相关专题

    更多
    c++和c语言的区别有哪些
    c++和c语言的区别有哪些

    c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

    2024.03.14

    2268

    9

    c++和python学习顺序推荐
    c++和python学习顺序推荐

    一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

    2024.03.14

    1039

    6

    python和c++学习性价比分析
    python和c++学习性价比分析

    Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

    2024.03.14

    447

    5

    c语言和c++一样吗
    c语言和c++一样吗

    c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    2024.03.14

    327

    5

    c语言和c++先学哪个好
    c语言和c++先学哪个好

    初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    2024.03.14

    426

    5

    c语言和c++的区别和联系
    c语言和c++的区别和联系

    c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    2024.03.14

    600

    5

    c++软件中文更改教程
    c++软件中文更改教程

    对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

    2024.03.21

    1429

    9

    python和java和c++学习性价比分析
    python和java和c++学习性价比分析

    Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

    2024.03.22

    1237

    7

    c++和c语言学习顺序推荐
    c++和c语言学习顺序推荐

    对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

    2024.03.25

    1325

    9

    热门下载

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

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    C++ Core Guidelines
    C++ Core Guidelines

    共0课时 | 0人学习

    C++ Reference
    C++ Reference

    共0课时 | 0人学习

    C++ 官方标准说明
    C++ 官方标准说明

    共0课时 | 0人学习