【发布时间】:2021-04-29 12:20:47
【问题描述】:
我有相当 大量 以 Base64 编码的数据 (>1MB)。
我找到了一个不错的library,它可以帮助我尽快处理这个问题。
这里是解码语法,很基础,需要一个输出缓冲区:
int base64_decode
( const char *src
, size_t srclen
, char *out
, size_t *outlen
, int flags
) ;
虽然我可以从他们的样本中获得输出缓冲区:
char out[1*1024*1024];
但是输入大小不是恒定的,在编译时询问这么大的大小看起来和感觉不好。另一方面,在堆栈上拥有一个不错的大缓冲区应该比在堆上存储和访问的数据具有一些速度优势 (source)。
但我想改用vector<char>。我可以将其定义为
std::vector<char> out;
然后当我有输入大小时,我可以resize它:
out.resize(input_size);
调整大小会将其所有项目初始化为 0,这对我来说似乎不切实际且不必要,因为 base64_decode 还会在下一步中初始化这些项目。
因此,resize 可能不是最好的,但调用 reserve 也无济于事,因为它不会修改向量的大小(尽管它也不会初始化项目)。
由于我没有关于数据大小的先验信息,我要么需要使用一些运行时可调整大小的缓冲区,要么进行大猜测并分配一个巨大的缓冲区。
由于库能够非常快地解码,我也想对输出缓冲区使用最快的解决方案,char array 和 vector 似乎都不合适。那么我最快的选择是什么?
【问题讨论】:
-
resize可能是您最快的解决方案。 CPU 很容易将char归零。我的建议,使用vector然后配置文件。如果性能好,那么你就完成了。如果不是,那么您至少有数据可以用来帮助选择更好的解决方案。 -
base64_decode不返回它能够解码的字节数吗?然后你不断地调用它,直到它返回 0,这意味着所有的数据都被解码了。使用过大的缓冲区 (>1MB) 对 CPU 缓存不利。但是也很容易预测 Base64 解码后的大小(基本上是 ~input*3/4+4)。 -
不,它不会以解码后的大小返回,而是将其放入
outlen。关于大小估计是的,一旦我们有了输入数据的长度,我就不难了。 -
您的堆栈数组只会在您放置它的函数调用期间消耗内存。分配/取消分配和初始化的开销为零。
std::vector分配/解除分配的速度会相当慢。 -
所以我应该在
base64_decode前面做char buffer[input_size]?