【问题标题】:What's the fastest way to figure out if a pointer is part of a set in C?确定指针是否是 C 中集合的一部分的最快方法是什么?
【发布时间】:2014-06-17 08:15:23
【问题描述】:

给定一个结构上的指针,我需要非常快速找出它是否是集合的一部分(我必须自己定义/实现)。 我可能会考虑像Bloom Filter 这样的技术,但我真的不知道如何在指针上做到这一点。

解决方案需要在 32 位和 64 位机器上运行。

编辑: 所有这些指针(其中 2k-5k)都指向各种随机内存地址,因为它们以我无法控制的双向链表的元素为目标。这可以改写为:“如何通过创建另一个结构在一个元素中查找是只读 双向链表的一部分?”

编辑 2: 双向链表可能会随着时间增长,但不是我控制的集合。

【问题讨论】:

  • 解释“集合的一部分”?什么套餐?你的意思是,找出指向结构的指针是否指向这些结构的给定数组的元素?
  • 我会更新我的问题,使其更准确,同时:所有这些结构(其中 2k-5k)都出现在我的“某种”双向链表中 zero 控制,但是,除了现有的 DLL 之外,我需要自己创建 set
  • 布隆过滤器是概率性的......你同意吗?
  • 您想要比遍历列表检查每个节点是否与指针匹配更快的方法吗?如果是这样,您还可以将每个候选指针存储在快速搜索的数据结构中(例如搜索树)。当然,这意味着每次修改链表时都必须维护搜索树(当然也可以在使用之前重建它)。
  • 回答“不知道如何在指针上执行”部分,转换为(uintptr_t)(此转换保证为双射)并使用您将在整数上使用的任何技术

标签: c set bloom-filter


【解决方案1】:

从您引用的页面:

Bloom 为应用程序提出了该技术,如果应用“常规”无错误散列技术,源数据量将需要内存中不切实际的大散列区域。他给出了一个用于 500,000 个单词的字典的断字算法示例,其中 90% 遵循简单的断字规则,但其余 10% 需要昂贵的磁盘访问来检索特定的断字模式。

如果您只有有 2k-5k 个项目,那么我怀疑您是在谈论“内存中不切实际的大散列区域”。

简而言之,我会推荐一个哈希表。您需要对数据进行一次 O(n) 传递以构建表格,然后查找将是 O(1)

【讨论】:

  • 感谢@ams 的回答。不幸的是,我有点害怕这个解决方案可能“慢”。并不是说 O(1) 不快,而是每次“运行”我必须执行此操作很多次(大约 50k-400k 次),而一次“运行”肯定不会花费更多那0.1毫秒。因此,我需要一些可以在 1e-10 秒内完成的事情。
  • 我目前担心的是哈希表和布隆过滤器都需要哈希,即使执行一次(有时使用布隆过滤器 (k) 执行更多),这可能是 瓶颈。抱歉,我应该从一开始就更清楚地了解性能方面。
  • @PatrickAllaert 试着弄清楚你想要的东西在理论上是否可行。
  • @PatrickAllaert 一个适合单个整数(指针)的散列函数可能不会很慢。您可能只是移开底部位(始终为零,因为 malloc 返回对齐的内存),并将大多数顶部位归零,这就足够了。这会给你一些二次方的表格大小。如果碰撞率太高,那么您需要更智能/更慢的东西,但值得一试。在任何情况下,一个带有数字的寄存器内小游戏肯定比遍历内存中的搜索树要快。
  • @PatrickAllaert 顺便说一句,2GHz 处理器上的 0.1ms 仅是 200k CPU 周期。在这么多周期中做 任何事情 400k 次将是一项挑战!
猜你喜欢
  • 2023-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
相关资源
最近更新 更多