C++实现海量数据去重Bitmap算法 _ 空间开销优化与查找【源码】

夜敏小哥_7504

夜敏小哥_7504

2026-05-06

775人浏览

原创

bitmap不能直接用std::vector做海量去重,因其非真正位容器,operator[]返回临时引用,不支持取地址、原子操作及正常迭代,且编译器难内联,性能比手写位操作慢2–3倍。

c++实现海量数据去重bitmap算法 _ 空间开销优化与查找【源码】

Bitmap 为什么不能直接用 std::vector<bool></bool> 做海量去重

它不是真正的位容器,而是空间优化的代理类,operator[] 返回的是临时 std::vector<bool>::reference</bool>,无法取地址、不能用于原子操作、迭代器行为异常;更关键的是——在频繁 set/test 场景下,编译器很难将其完全内联,实测比手写位操作慢 2–3 倍。海量数据(比如 10 亿整数)去重时,这点开销会被放大。

实操建议:

  • std::vector<uint64_t></uint64_t> 或裸 uint8_t* + 手动位运算,确保每次 set()test() 都编译为单条 btsbt 汇编指令(GCC/Clang 下加 -O2 -march=native 可触发)
  • 数组长度按 (max_value + 63) / 64 计算,避免越界;若值域不从 0 开始(如全是正整数但最小为 1000000),需做偏移预处理,否则浪费大量前导零空间
  • 不要用 std::bitset<n></n>,N 必须是编译期常量,10 亿规模会直接导致编译失败或栈溢出

如何让 Bitmap 支持 10^9 级别整数且内存不爆掉

核心是控制位图总长度。假设去重对象是 32 位无符号整数(0 ~ 4294967295),全量 Bitmap 需要 512MB 内存(4294967296 / 8)。但真实场景中,数据往往稀疏:10 亿个 int,实际值域可能只覆盖 2 亿个不同数字。这时硬分配 512MB 就是浪费。

实操建议:

  • 先扫描一遍数据,统计 min/max,再按 (max - min + 63) / 64 分配 std::vector<uint64_t></uint64_t>,可压缩 70%+ 内存(例如 min=1000000, max=210000000 → 仅需 ~26MB)
  • 若 min/max 跨度过大(如 0 和 4e9 同时出现),但有效值数量有限,改用分段 Bitmap:按高 16 位分桶,每桶内用 16 位 offset 构建子 Bitmap,总内存 ≈ 桶数 × 8KB,支持查重 + 迭代,且 cache 友好
  • 避免用 new uint8_t[big_size] 直接分配,优先用 mmap(MAP_ANONYMOUS)(Linux)或 VirtualAlloc(Windows),延迟提交物理页,OOM 风险更低

test_and_set() 必须是原子的,否则多线程去重结果错乱

Bitmap 常用于日志去重、爬虫 URL 去重等并发写场景。多个线程同时对同一 bit 调用 set(),若非原子,会出现“已存在却重复插入”的逻辑错误——这不是数据损坏,而是业务语义失效。

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载

实操建议:

  • __builtin_expect + __atomic_fetch_or(GCC/Clang)或 InterlockedOr64(MSVC)实现真正原子的 test_and_set(),返回旧值,据此判断是否首次命中
  • 不要用 std::atomic<uint64_t></uint64_t> 数组模拟位操作:它保证字宽原子性,但单 bit 操作仍需 read-modify-write 循环,性能差且易活锁
  • 若只读不写(如预载入后只查),可去掉原子逻辑,改用 __builtin_popcountll 加速批量 test

查找某个数是否已存在,为什么 test(x) 要拆成两步计算

位图本质是“值 → 位偏移”的映射。直接 bitmap[x >> 6] & (1ULL 看似简洁,但 x 为负数、或 x 超出预分配范围时,会静默越界读——UB 不报错,但可能读到相邻内存,返回假阳性。

实操建议:

  • 封装 test(uint32_t x) 时,必须先校验 x >= offset && x (offset 是 min 值),否则返回 false;不要依赖 caller 保证输入合法
  • 位索引计算统一用无符号右移:x >> 6 替代 x / 64x & 63 替代 x % 64,避免负数除法陷阱
  • 若需支持 64 位整数去重,用 uint64_t 数组 + x >> 6 依然可行,但注意 1ULL 中 <code>x & 63 必须是 int 类型,否则高位截断

真正难的不是实现 set/test,而是决定「哪些数值得放进 Bitmap」——值域估算偏差 10 倍,内存就差一个数量级;而原子操作的正确性,往往在压测时才暴露。别省那几行边界检查。

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

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

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

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

2024.03.14

2068

9

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

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

2024.03.14

939

6

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

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

2024.03.14

367

5

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

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

2024.03.14

307

5

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

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

2024.03.14

346

5

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

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

2024.03.14

560

5

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

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

2024.03.21

1389

9

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

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

2024.03.22

1177

7

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

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

2024.03.25

1305

9

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Valgrind Quick Start Guide
Valgrind Quick Start Guide

共0课时 | 0人学习

CLion CMake 快速入门教程
CLion CMake 快速入门教程

共0课时 | 0人学习