问题描述
我有三个 uint32_t
,当它们组合在一起时,它们将生成一个唯一的密钥。我必须这样做大约 100M 或更多,并且可能每天数次并将其存储在键值数据库中。我想保持尽可能少的字节数。我正在按以下方式进行操作,但我很好奇是否有更快的方法来做到这一点。
char *key = xmalloc(snprintf(NULL,"%" PRIu32 "-%" PRIu32 "-%" PRIu32,num1,num2,num3) + 1);
sprintf(key,num3);
解决方法
-
转换为十进制表示的成本相当高。如果使用十六进制,您可以获得更快的转换:
Compute Instance's
-
正如@AKX 提到的,使用固定大小的缓冲区。由于字符串(大概)被复制到数据库中,因此您不必担心它在数据库中占用了不必要的空间:
sprintf(key,"%" PRIx32 "-%" PRIx32 "-%" PRIx32,num1,num2,num3);
数据库引擎不知道您过度分配了缓冲区。它将根据字符串的实际长度而不是缓冲区的大小分配自己的内存。
-
实现您自己的十六进制格式。
char key[32]; snprintf(key,sizeof(key),num3);
需要解析其格式字符串并在运行时根据参数列表对其进行解释。对于像您这样的任务,这具有不可忽视的开销。相反,您可以进行自己的snprintf
-to-hex 转换,专门用于您的任务。我会使用int32
作为数字而不是传统的"abcdefghijklmnop"
。 -
您的键值数据库是否需要文本编码键?如果没有,您可以尝试对您的密钥进行二进制编码(例如,查看 SQLite4 varint encoding 以获得灵感)。
如果您更喜欢文本编码的键,我会将 Yakov 的建议更进一步(好吧,两步)并使用 base64 编码而不是十六进制。这样你就可以将 6 位打包成一个字符,而不是只有 4 位。
该实现将有多个位移加查找表。我敢打赌它会比 printf
快。