首页 > 解决方案 > 转换三个 uint32_t 以在 C 中生成唯一键的更快方法

问题描述

我有三个uint32_t组合在一起时,它们将生成一个唯一的密钥。我必须每天执行大约 100M 或更多,并且可能会执行多次,并将其存储在键值数据库中。我想将密钥保持在尽可能少的字节数。我正在按照以下方式进行操作,但我很好奇是否有更快的方法来执行此操作。

char *key = xmalloc(snprintf(NULL, 0, "%" PRIu32 "-%" PRIu32 "-%" PRIu32,num1,num2,num3) + 1);   
sprintf(key, "%" PRIu32 "-%" PRIu32 "-%" PRIu32, num1,num2,num3);

标签: cperformanceconcatenationunique-keyuint32

解决方案


  • 转换为十进制表示是相当昂贵的。如果您使用十六进制,您可以获得更快的转换:

      sprintf(key, "%" PRIx32 "-%" PRIx32 "-%" PRIx32, num1, num2, num3);
    
  • 正如@AKX 提到的,使用固定大小的缓冲区。由于字符串(可能)被复制到数据库中,因此您不必担心它在数据库中占用的空间超过所需空间:

      char key[32];
      snprintf(key, sizeof(key), "%" PRIx32 "-%" PRIx32 "-%" PRIx32, num1, num2, num3);
    

    数据库引擎不知道您过度分配了缓冲区。它将根据字符串的实际长度而不是缓冲区的大小来分配自己的内存。

  • 实现您自己的十六进制格式。snprintf需要在运行时解析其格式字符串并根据参数列表对其进行解释。对于像您这样的任务,这具有不可忽略的开销。相反,您可以进行自己的int32- 到十六进制转换,专门用于您的任务。我会使用"abcdefghijklmnop"数字而不是传统的"0123456789abcdef".

  • 您的键值数据库是否需要文本编码的键?如果没有,您可以为您的密钥尝试二进制编码(例如,查看SQLite4 varint encoding以获得灵感)。


推荐阅读