在像遊戲之類的實時應用程序中,它通常可為每個實體提供一個名稱。這使跟踪錯誤更容易,因為通過唯一名稱找到實體比查看唯一數字或其他形式的標識符更容易。但是字符串是巨大的,並且複制和比較它們的速度很慢,因此通常無法在性能關鍵代碼中使用它們。
一種解決方案是哈希字符串,它們僅是整數,因此很小,可以快速復制和比較。但是哈希不允許檢索原始的字符串值,這正是記錄和調試目的所需的內容!此外,有可能發生碰撞,因此相等的哈希代碼不一定意味著平等的字符串。這個機會很小,但是很難找到錯誤的來源。
另一個解決方案是字符串Industing。 String Indusning使用一個全局查找表,其中每個字符串僅存儲一次,並通過索引或類似的內容引用。複製和比較也很快,但是它們仍然並不完美:您只能在運行時訪問它們。在編譯時(例如,為開關獲取值)是不可能的。
因此,一方面,我們希望快速輕巧的標識符,但另一方面,也可以使用該名稱恢復。
This open source library provides a mix between the two solutions in the form of the class string_id .每個對像都存儲一個Hashed String值和指向存儲原始字符串值的數據庫。這允許在需要時檢索字符串值,同時還可以從Hashed字符串中獲得性能收益。此外,數據庫可以檢測可以通過自定義碰撞處理程序處理的碰撞。有一個用戶定義的文字來創建一個編譯時間散列的字符串值,以將其用作恆定表達式。
數據庫可以是從某個接口類得出的任何用戶定義類型。有幾個預定義的數據庫。這包括一個沒有存儲任何東西的虛擬數據庫,其他數據庫使其使其線程安全的適配器以及一個高度優化的數據庫,以有效地存儲和檢索字符串。 A typedef default_database is one of those databases and can be set via the following CMake options:
FOONATHAN_STRING_ID_DATABASE - if OFF , the database is disabled completely, eg the dummy database is used.這不允許檢索字符串或碰撞檢查,但不需要那麼多記憶。 It is ON by default.
FOONATHAN_STRING_ID_MULTITHREADED - if ON , database access will be synchronized via a mutex, eg the thread safe adapter will be used.如果禁用數據庫,則無效。 Default value is ON .
有特殊的發電機類。它們的接口與標準庫中的隨機數生成器相似,但是生成字符串標識符。這用於以自動化的方式生成一堆標識符。發電機還要注意總是生成新的標識符。這也可以通過類似於碰撞處理的處理程序來控制。
有關示例,請參見示例/main.cpp。
它目前使用FNV-1A 64位哈希。碰撞確實很少見,我已經測試了219,606個英語單詞(小寫),並混合了很多數字,沒有遇到一次碰撞。由於這是標識符的正常用例,因此哈希功能非常好。此外,哈希值的分佈很好,並且很容易計算。
該數據庫使用專門的哈希表。存儲液索引的碰撞通過單獨的鏈條和單個鏈接列表來解決。每個節點直接包含字符串,而無需其他內存分配。使用哈希值對鏈接列表上的節點進行排序。這允許有效檢索和檢查是否已經有一個存儲相同哈希值的字符串。這使其比以前使用過的STD :: Unordered_map非常有效,更快(至少比我用於基準測試的LibstDC ++實現更快)。
該庫是根據以下編譯器編譯的:
Constexpr,NoExcept,覆蓋和字面運營商有兼容性選項和替代Marcos。原子處理程序功能可以選擇被禁用,並且默認情況下可以使用GCC 4.6,因為它不支持它們。