转储GHashTable到文件

时间:2013-03-27 14:19:34

标签: c hashtable glib

在我的应用程序中,我需要将Glib GHashTable实例保存到磁盘中,然后再加载到内存中。但我找不到任何直接转储实例的方法。

选项不是直接保存GHashTable,而是一个接一个地保存条目。加载时,逐个加载条目,然后插入新的哈希表。但我发现执行此操作需要很长时间:

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

加载6000万个条目大约需要20分钟。如果我只是加载条目但不执行插入,则只需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分钟:

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);
}

我的大多数输入键m->s都有~60位。

3 个答案:

答案 0 :(得分:3)

GHashTable未针对该数据集的大小进行优化。你最好自己编写自己的哈希表。

答案 1 :(得分:3)

您应该查看当前GIO和dconf专用的gvdb代码。 gvdb是一个哈希表,针对通过mmap()进行读取进行了优化:

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

它使用GVariant将数据存储在内存有效的二进制表示中。代码在LGPL v2.1 +下,因此只能在具有兼容许可证的项目中进行剪切和粘贴。

答案 2 :(得分:1)

我同意ebassi(以及iain和unwind)GHashTable可能不适合您的用例。

SQLite应该可以正常工作,但也有很多非常快速的嵌入式键值存储可用。 Wikipedia page for dbm列出了很多。如果我是你,我可能会使用Tokyo CabinetLevelDB或(如果您的项目与GPL兼容),Kyoto Cabinet

此外,您应该考虑slice allocator而不是malloc。您仍然需要长时间加载和保存(通过使用嵌入式数据库可以消除),但它应该比malloc快得多。或者,如果您可以使用32位密钥而不是64位密钥,则可以使用GINT_TO_POINTER并加快速度。