2013-03-27 88 views
2

在我的應用程序中,我需要將Glib GHashTable實例保存到磁盤中,然後再加載到內存中。但我找不到任何方式直接轉儲實例。將GHashTable轉儲到文件

一個選項不是直接保存GHashTable,而是一個接一個地保存條目。加載時,逐個加載條目,並插入新的散列表。但我發現,它需要太多的時間來執行此操作:

g_hash_table_insert(hash, (gpointer) (mer_v), (gpointer) m); 

它需要大約20分鐘,負載60萬個條目。如果我只是加載條目但不執行插入操作,則只需要10秒。

那麼有沒有其他方法可以有效地保存GHashTable?由於

======================

更新:

我的哈希表鍵是uint64_t中。此代碼爲10秒左右運行:

for (i = 0; i < 60000000; i++) { 
    tmp = (uint64_t*) malloc (sizeof(uint64_t)); 
    *tmp = i; 
    g_hash_table_insert(hash, (gpointer) (tmp), (gpointer) tmp); 
} 

但這代碼運行了超過10分鐘:

我輸入鍵 m->s
for (i = 0; i < meta->n_kmers; i++) { 
    m = g_ptr_array_index(kmer_list, i); 
    tmp = (uint64_t*) malloc (sizeof(uint64_t)); 
    *tmp = m->s; 
    g_hash_table_insert(hash, (gpointer) (tmp), (gpointer) tmp); 
} 

大部分是用〜60位。

+2

我認爲你的用例有點超過了GHashTable的「舒適」設計大小......它甚至沒有提供一個大小的構造函數,這將有助於減少重新分配的次數它肯定會在你的情況下做。 – unwind 2013-03-27 14:48:38

+0

@unwind是否有更高效率的替代庫/代碼?我不想自己寫。 – Joy 2013-03-28 08:07:23

回答

3

GHashTable未針對數據集的大小進行優化。你最好編寫自己的哈希表。

+0

我試過C++'std:unordered_map',大約需要40秒來加載整個數據結構。好。 – Joy 2013-04-04 07:51:22

3

你應該看看當前GIO和dconf專用的gvdb代碼。 gvdb是用於經由MMAP()讀取優化的哈希表:

https://git.gnome.org/browse/glib/tree/gio/gvdb/

它使用GVariant將數據存儲在存儲器中的高效的二進制表示。該代碼在LGPL v2.1 +下,因此只能在兼容許可證的項目中剪切和粘貼。

+0

在gvdb-builder中。h,我發現:'GHashTable * gvdb_hash_table_new(GHashTable * parent,const gchar * key)'。所以我需要首先有一個GHashTable?我不太明白如何使用它。有沒有文件?我的哈希表有uint64_t鍵和指針值。謝謝。 – Joy 2013-03-28 02:46:18

+0

gvdb使用字符串鍵來尋址字符串鍵和變體值的散列表。如果你要存儲64位整數和隨機指針值,那麼你可以將它們包裝成gvdb代碼所期望的格式(即字符串和變體),否則你將不得不編寫自己的數據類型。 – ebassi 2013-04-02 22:08:56

1

我同意ebassi(和iain,並放鬆),GHashTable可能不適合您的用例。

SQLite應該可以正常工作,但也有很多非常快的嵌入式鍵值存儲。 Wikipedia page for dbm列出了很多。如果我是你,我可能會使用Tokyo Cabinet,LevelDB或(如果你的項目是GPL兼容的),Kyoto Cabinet

此外,而不是malloc,你應該考慮slice allocator。你仍然需要長時間的加載和保存(通過使用嵌入式數據庫你可以省去),但它應該比malloc快很多。或者,如果您可以使用32位密鑰而不是64位密鑰,則只需使用GINT_TO_POINTER即可,而且速度更快。