在C

问题描述

我有三个 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 快。