在像游戏之类的实时应用程序中,它通常可为每个实体提供一个名称。这使跟踪错误更容易,因为通过唯一名称找到实体比查看唯一数字或其他形式的标识符更容易。但是字符串是巨大的,并且复制和比较它们的速度很慢,因此通常无法在性能关键代码中使用它们。
一种解决方案是哈希字符串,它们仅是整数,因此很小,可以快速复制和比较。但是哈希不允许检索原始的字符串值,这正是记录和调试目的所需的内容!此外,有可能发生碰撞,因此相等的哈希代码不一定意味着平等的字符串。这个机会很小,但是很难找到错误的来源。
另一个解决方案是字符串Industing。 String Indusning使用一个全局查找表,其中每个字符串仅存储一次,并通过索引或类似的内容引用。复制和比较也很快,但是它们仍然并不完美:您只能在运行时访问它们。在编译时(例如,为开关获取值)是不可能的。
因此,一方面,我们希望快速轻巧的标识符,但另一方面,也可以使用该名称恢复。
该开源库以类String_id的形式提供两个解决方案之间的混合。每个对象都存储一个Hashed String值和指向存储原始字符串值的数据库。这允许在需要时检索字符串值,同时还可以从Hashed字符串中获得性能收益。此外,数据库可以检测可以通过自定义碰撞处理程序处理的碰撞。有一个用户定义的文字来创建一个编译时间散列的字符串值,以将其用作恒定表达式。
数据库可以是从某个接口类得出的任何用户定义类型。有几个预定义的数据库。这包括一个没有存储任何东西的虚拟数据库,其他数据库使其使其线程安全的适配器以及一个高度优化的数据库,以有效地存储和检索字符串。 Typedef default_database是其中一个数据库之一,可以通过以下CMAKE选项设置:
foonathan_string_id_database-如果关闭,则完全禁用数据库,例如使用虚拟数据库。这不允许检索字符串或碰撞检查,但不需要那么多记忆。默认情况下它是打开的。
foonathan_string_id_multithreaded-如果在ON上,数据库访问将通过MUTEX同步,例如,将使用线程安全适配器。如果禁用数据库,则没有效果。默认值已打开。
有特殊的发电机类。它们的接口与标准库中的随机数生成器相似,但是生成字符串标识符。这用于以自动化的方式生成一堆标识符。发电机还要注意总是生成新的标识符。这也可以通过类似于碰撞处理的处理程序来控制。
有关示例,请参见示例/main.cpp。
它目前使用FNV-1A 64位哈希。碰撞确实很少见,我已经测试了219,606个英语单词(小写),并混合了很多数字,没有遇到一次碰撞。由于这是标识符的正常用例,因此哈希功能非常好。此外,哈希值的分布很好,并且很容易计算。
该数据库使用专门的哈希表。存储液索引的碰撞通过单独的链条和单个链接列表来解决。每个节点直接包含字符串,而无需其他内存分配。使用哈希值对链接列表上的节点进行排序。这允许有效检索和检查是否已经有一个存储相同哈希值的字符串。这使其比以前使用过的STD :: Unordered_map非常有效,更快(至少比我用于基准测试的LibstDC ++实现更快)。
该库是根据以下编译器编译的:
Constexpr,NoExcept,覆盖和字面运营商有兼容性选项和替代Marcos。原子处理程序功能可以选择被禁用,并且默认情况下可以使用GCC 4.6,因为它不支持它们。