我正在尝试将二进制格式转换为十六进制格式,二进制数据每秒都有一个流程,我的代码如下:
for(int i = 0; i < strlen(s); i++)
{
sprintf(in+i*2, "%02x", s[i]);
}
fprintf(fp, "%s\n", in);
但它太慢,因为数据如此迅速地进入。
有没有更好的方法来处理它?</ p>
是否有像fnprintf(fp,size,“%。* 02x \ n”,num,in)这样的函数?
答案 0 :(得分:3)
第一个问题是你在循环的每次传递中调用strlen
。请注意,strlen
必须计算字节数,直到找到字符串的结尾。如果您的字符串长度为100个字节,则循环将调用strlen
100次,每次strlen
将计算100个字节。结果是strlen
将在循环结束前计算总共10000个字节。
第二个问题是你在每次循环中都会调用sprintf
。 printf
系列的所有成员都具有相当重的功能,在高性能代码中应该避免使用。鉴于将字节转换为两位十六进制数字很容易,您实际上并不需要sprintf
。
所以,如果您消除strlen
和sprintf
,代码会是什么样子。 (通过检查输出缓冲区溢出,我也投入了一些安全性。这就是bend
正在使用的内容。)
#define BUFSIZE 200
int digit;
char *sptr, *bptr, *bend;
char string[BUFSIZE];
char buffer[BUFSIZE];
bptr = buffer;
bend = &buffer[BUFSIZE - 2];
for ( sptr = string; *sptr != '\0'; sptr++ )
{
digit = (*sptr >> 4) & 0xf;
*bptr++ = ( digit > 9 ) ? digit + 'a' - 10 : digit + '0';
digit = *sptr & 0xf;
*bptr++ = ( digit > 9 ) ? digit + 'a' - 10 : digit + '0';
if ( bptr >= bend )
break;
}
*bptr = '\0';
fprintf( fp, "%s\n", buffer );
答案 1 :(得分:1)
一些事情:
在循环条件中停止使用strlen()
。编译器可以意识到它的值是恒定的并且优化了重复,这是可行的,但是为什么在你不需要首先使用它时依赖它呢?
停止使用这种昂贵的功能来解决一项微不足道的任务。所有你关心的是在每个字节中输出两个半字节的字符数字,所以这样做:
您很难用fputc
的潜在宏版本来击败简单查找序列的性能。转储到缓冲的io流时,您可能会处于或接近epsilon开销:
#include <stdio.h>
#include <stdlib.h>
void hex_dump(FILE *fp, const void *src, size_t slen)
{
static const char digits[] = "0123456789abcdef";
const unsigned char *p = src;
while (slen--)
{
putc(digits[(*p >> 4) & 0xF], fp);
putc(digits[*p++ & 0xF], fp);
}
putc('\n', fp);
}
int main()
{
const char msg[] = "A simple message to print";
hex_dump(stdout, msg, sizeof(msg));
}
<强>输出强>
412073696d706c65206d65737361676520746f207072696e7400
注意:我选择putc
是故意的。它可以(并且经常是)一个宏,它可以缓冲FILE
流的缓冲。理由:Faaaast。
当然,您可以使用简单的strlen
转发器来解决上述问题。如:
void hex_dump_str(const char *s)
{
hex_dump(s, strlen(s));
}
或者完全自定义它以在nulchar上终止并消除strlen
扫描,因为您可以在实际转储到流时执行此操作。这是你的选择。类似的东西:
void hex_dump_str(FILE *fp, const char *src)
{
static const char digits[] = "0123456789abcdef";
const unsigned char *p = (const unsigned char*)src;
while (*p)
{
putc(digits[(*p >> 4) & 0xF], fp);
putc(digits[*p++ & 0xF], fp);
}
putc('\n', fp);
}
祝你好运。