在 set、vector 与 vector 之间进行选择以用作位图(位集/位数组)

2023-12-14

给定一系列索引(标识符),我想将每个索引映射到一个布尔值,即:

// interface pseudocode
interface bitmap {
  bool identifier_is_set(unsigned int id_idx) const;
  void set_identifier(unsigned int id_idx, bool val) const;
};

这样我就可以设置和查询每个ID(索引)(如果设置或未设置),您更喜欢用什么来实现这个?

我认为这称为位数组或位图或位集,如果我错了,请纠正我。

假设最大标识符是预定的并且不大于1e6(1m),可能小得多(10k - 100k)。(这意味着 sizeof(int)*maximum_id_idx 使用的大小很容易适合内存。)

到目前为止我看到的可能的解决方案:

  • std::set<size_t>- 根据需要向该集合中添加或删除标识符。只要我们有稀疏位图,就允许任意大的标识符。
  • std::vector<bool>- 调整为适当的最大值,为每个 id_idx 存储 true 或 false。
  • std::vector<char>- 同样的事情,但没有遭受奇怪的困扰std::vector<bool>问题。使用的内存少于vector<int>.
  • std::vector<int>- 使用int作为布尔标志来拥有使用机器自然字大小的容器。 (不知道这是否会有所作为。)

请回答您更喜欢哪种容器类型以及原因,考虑到上面引用的最大 ID 限制,特别是考虑到表现的方面querying位图(插入性能并不重要)。

注:接口使用vector vs. set没关系,因为无论如何它都会隐藏在它的包装类后面。

编辑:添加关于 std::bitset 的讨论: std::bitset 将把整个数组大小合并到对象中,即 sizeof(std::bitset) 的大小约为 1/8 MB ,这会产生一个巨大的单个对象,并且会产生一些您无法再放入堆栈中的东西(这可能相关,也可能不相关)。


在不知道您运行此代码的平台和访问模式的情况下,很难说是否vector<bool>会比vector<char> (or vector<int>) 甚至set<int> or unordered_set<int>.

例如,如果您有一个极其稀疏的数组,则线性搜索vector<int>仅包含索引集可能是最好的答案。 (请参阅 Mike Abrash 关于针对 x86 优化 Pixomatic 的文章。)

另一方面,您可能有一个有点稀疏的数组。我所说的有点稀疏是指集合元素的数量远大于 L1 或 L2。在这种情况下,更多的低级细节以及您的实际访问模式开始发挥作用。

例如,在某些平台上,可变位移位非常昂贵。因此,如果您正在查询一组随机标识符,则执行此操作的频率越高,查询的次数就越多。vector<char> or vector<int>成为一个更好的主意bitset<...> or vector<bool>。 (后两者使用移位来查找位。)另一方面,如果您按顺序迭代稀疏位向量并且只需要位集,则可以优化该迭代以消除变量移位的开销。

此时,您可能还想知道稀疏标识符实际上是如何分布的。如果它们聚集在一起,您需要知道最佳内存读取大小和一次读取一个字符之间的权衡。这将决定更频繁地访问缓存是否会抵消非本机大小数据的读取。

如果标识符分散,您可以通过使用哈希集获得重大胜利(unordered_set<int>) 而不是位向量。但这取决于负载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 set、vector 与 vector 之间进行选择以用作位图(位集/位数组) 的相关文章

  • 快速检查网络速度

    我想从我的 swift 应用程序检查网络速度 我发现很多帖子描述了Reachability特别是查找连接是否可达以及是 WIFI 连接还是 WWAN 连接的方法 我的问题 是否可以检测 WWAN 的类型 2G 3G 4G 你可以用以下命令检
  • 如何调试参数化 SQL 查询

    我使用 C 连接到数据库 然后使用 Ad hoc SQL 来获取数据 这个简单的 SQL 查询非常方便调试 因为我可以记录 SQL 查询字符串 如果我使用参数化 SQL 查询命令 有没有办法记录 sql 查询字符串以进行调试 我想就是这样的
  • 将 2D 数组映射到 1D 数组

    我想用一维数组来表示一个二维数组 函数将传递两个索引 x y 和要存储的值 这两个索引代表一维数组的单个元素 并相应地设置它 我知道一维数组需要具有 arrayWidth arrayHeight 的大小 但我不知道如何设置每个元素 例如 如
  • 如何在 C# 事件中区分更改是由代码还是由用户进行?

    我有一个简单的TextBox一开始是空的 我有一个简单的事件 TextChanged 可以知道用户何时更改了其中的任何内容TextBox 但是 如果我自己在代码中对其执行任何操作 该事件就会触发 喜欢设置textbox Text Test
  • 有没有比这更快的方法来查找目录和所有子目录中的所有文件?

    我正在编写一个程序 需要在目录及其所有子目录中搜索具有特定扩展名的文件 这将在本地驱动器和网络驱动器上使用 因此性能是一个问题 这是我现在使用的递归方法 private void GetFileList string fileSearchP
  • 当我单击 GridView 项时返回 ImageView 实例

    当我点击GridView项时如何返回ImageView实例 我为 ItemClick 创建自定义绑定事件 public class ItemClickSquareBinding MvxBaseAndroidTargetBinding pri
  • 阅读 Stack Overflow RSS 源

    我正在尝试获取未回答问题的列表the feed https stackoverflow com feeds 但我在阅读时遇到困难 const string RECENT QUESTIONS https stackoverflow com f
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • 记录 Google Cloud SQL PostgreSQL 实例上的慢速查询

    我工作的公司使用 Google Cloud SQL 来管理生产中的 SQL 数据库 我们遇到了性能问题 我认为查看 监控高于特定阈值 例如 250 毫秒 的所有查询是一个好主意 除其他外 通过查看PostgreSQL 文档 https ww
  • Android:了解 OnDrawFrame、FPS 和 VSync (OpenGL ES 2.0)

    一段时间以来 我在 Android 游戏中遇到了运动精灵间歇性 卡顿 的情况 这是一个非常简单的 2D OpenGL ES 2 0 游戏 这是一个持续存在的问题 我已经多次重新访问过 在我的游戏循环中 我有 2 个 计时器 一个用于记录前一
  • CMake - 将预构建库链接到 C# 项目

    我正在使用 CMake 构建 C 库 该库依赖于已构建的库 dll 我似乎无法让图书馆链接到我的图书馆 我尝试过使用target link libraries mylib external lib 我也尝试过暴力破解 reference e
  • for 循环 - 没有效果的语句

    由于某种原因 我收到错误 statement with no effect关于这个声明 for j idx j lt iter j increment printf from loop idx i int idx punc ctxt j 你
  • 使用 Linq 进行异步Where过滤

    我有一个List通过填充的元素async调用 WebService 没问题 我需要过滤该列表以便在应用程序视图上显示某些内容 我试过这个 List
  • 如何从枚举中选择随机值?

    给定 C 中的任意枚举 如何选择随机值 我没有找到这个非常基本的问题 我会在一分钟内发布我的答案作为任何人的参考 但请随意发布你自己的答案 Array values Enum GetValues typeof Bar Random rand
  • 通过 MSBuild 调用 cl.exe 时无限期挂起

    我正在尝试在我的 主要是 C 项目上运行 MSBuild 想象一下一个非常庞大的代码库 Visual Studio 2015 是有问题的工具集 Windows 7 SP1 和 VS 2015 更新 2 即使使用 m 1 从而迫使它仅使用一个
  • 改进C++逐行读取文件的能力?

    我正在解析大约 500GB 的日志文件 我的 C 版本需要 3 5 分钟 我的 Go 版本需要 1 2 分钟 我正在使用 C 的流来流式传输文件的每一行以进行解析 include
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • ASP.NET Core:会话 ID 始终变化

    今天启动了一个全新的 ASP NET Core 网站 按照说明添加会话 我们在索引页上打印出会话 ID 它始终是唯一的 我认为这可能是 cookie 合规性 所以我在 Chrome 的高级设置和调试器中删除了所有 cookie 但横幅不会再
  • 当我读取 500MB FileStream 时出现 OutOfMemoryException

    我使用 Filestream 读取大文件 gt 500 MB 但出现 OutOfMemoryException 任何有关它的解决方案 我的代码是 using var fs3 new FileStream filePath2 FileMode
  • 在 C# 中读取/写入命令行程序

    我正在尝试与 C 的命令行程序进行对话 它是一个情绪分析器 它的工作原理如下 CMD gt java jar analyser jar gt Starting analyser 这是我想从我的 C 程序插入内容的地方 例如 I love y

随机推荐