我在c ++中创建一个十六进制到二进制转换函数时考虑到了一点效率,并且由于iostream的十六进制说明符不适用于字符(!?!),我决定使用sscanf。 它从一个向量读取并写入另一个向量。 问题是,在其中一个案例中,程序非常缓慢。 这是一个例子:它将〜260000个字符串复制到矢量中 然后在循环中,输入中的两个十六进制字符将在输出中转换为一个字节。
该字符串位于文件" key.h"中。它有这样的东西:
const char *key={
"6e7fdb71e32c5f8420100028201010.... {260000 characters more} ..."}
,
#include <cstring>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
//262150 kilobyte file, constainig a large string, assigned to the variable key
#include "key.h"
//hex to bin conversion demo
int main()
{
std::vector<char> in;
std::vector<char> out;
//output buffer size is half of the input buffer size
out.resize(strlen(key)/2);
//read hex string into vector
in.insert(in.begin(),&key[0],&key[strlen(key)]);
for (unsigned int bi = 0; bi < in.size()/2; ++bi) {
#if 0 //this version is VERY slow
const char *ptr = &in[2*bi];
#else //but not this
char ptr[2];
memcpy(ptr,&in[2*bi],2);
#endif
sscanf(ptr, "%2hhX", &out[bi]);
}
}
现在问题:在这种状态下,程序会给出以下结果:
time ./test
real 0m0.024s
user 0m0.024s
sys 0m0.000s
将#if 0改为#if 1和...... magic:
time ./test
real 0m0.611s
user 0m0.610s
sys 0m0.001s
慢25倍。唯一的区别是,在第二个版本中,sscanf接收指向输入向量存储器的指针
在第一种情况下,向量内容被复制到堆栈上的本地缓冲区,然后使用指向此缓冲区的指针调用sscanf。
那么,为什么第二种情况如此缓慢?