在我的应用程序中,我需要将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位。
答案 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 Cabinet,LevelDB或(如果您的项目与GPL兼容),Kyoto Cabinet。
此外,您应该考虑slice allocator而不是malloc。您仍然需要长时间加载和保存(通过使用嵌入式数据库可以消除),但它应该比malloc快得多。或者,如果您可以使用32位密钥而不是64位密钥,则可以使用GINT_TO_POINTER并加快速度。