【问题标题】:"Compile-time hashtable" in CC中的“编译时哈希表”
【发布时间】:2014-05-09 18:14:06
【问题描述】:

我正在用 C 语言实现一段类似这样的逻辑(对于解释器):

if <input string> in <list of pre-defined constant strings>
  do_a_predefined_action()
else
  do_something_else(<input string>)

我的第一个想法是哈希表,但如果常量字符串在编译时已知,则必须在运行时手动初始化哈希表似乎有点浪费。

我的其他想法包括静态初始化具有已知哈希值的哈希表结构(ick...),然后像平常一样简单地使用它。另一个是一个巨大的嵌套switch 块,它将提供O(log n) 查找时间(不如哈希表快)。

查找一组预定义字符串的最佳方法是什么?我还没有看到什么解决方案?优雅比速度更受欢迎。

【问题讨论】:

  • 我会在启动时构建哈希表并完成它。稍后,如果您因此认为启动时间不可接受,您可以编写某种预处理器,预先构建哈希表以供包含。
  • @500-InternalServerError:如果没有更好的路线,这就是我打算走的路。我对我的代码非常强迫,而且启动的东西看起来很丑。感谢您的输入。 :-)

标签: c hashtable compile-time


【解决方案1】:

我不会太担心在程序启动时初始化哈希表的成本。这有点过早优化的味道。也就是说,...

由于您确实知道所有字符串,因此您可以考虑为这些字符串构造一个完美哈希。您可以使用一些工具来尝试许多可能的散列算法并选择最适合数据的算法。这将导致静态初始化路由。尽管您已经对此策略发表了“恶心”的评论。如果速度问题真的非常重要,我鼓励您重新考虑。


我实际上已经在我的 postscript 解释器的上下文中考虑过这个问题,它在启动时初始化 systemdict 哈希表。要考虑的另一条路线是将表缓存在文件中。用于初始化的伪代码将如下所示:

check for cached file
if file exists,
    load it.
if file does not exist,
    initialize table manually.
    save table to file.

【讨论】:

  • 虽然@Hasturkun 最先到达并回答了我的问题,但您的回答很有道理,而我正在过早地进行优化。感谢您的帮助!
【解决方案2】:

您可以使用gperf 或Bob Jenkin's Minimal Perfect Hash 之类的代码来生成(可能是最小的)Perfect Hash Function,它将字符串映射到值,稍后您可以使用switch。

【讨论】:

  • 如果输入字符串不在字符串常量列表中,这将如何工作?你仍然需要检查字节匹配,以防你得到一个错误的命中。
  • @Anonymous:默认情况下,gperf 在匹配后会额外执行一个strcmp 以进行验证。另一个没有(但这不应该太难实现)。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 2014-01-22
  • 2017-10-18
  • 1970-01-01
  • 2023-03-04
  • 2013-08-20
  • 2012-10-03
相关资源
最近更新 更多