我需要逐字节读取两个1MB +二进制文件,比较它们 - 如果它们不相等,则从不等字节开始打印下16个字节。要求是它只运行5毫秒。目前,如果不等位位于两个文件的末尾,我的程序将花费19毫秒。关于如何优化它,有什么建议吗?
#include <stdio.h> //printf
#include <unistd.h> //file open
#include <fcntl.h> //file read
#include <stdlib.h> //exit()
#include <time.h> //clock
#define SIZE 4096
void compare_binary(int fd1, int fd2)
{
int cmpflag = 0;
int errorbytes = 1;
char c1[SIZE], c2[SIZE];
int numberofbytesread = 1;
while(read(fd1, &c1, SIZE) == SIZE && read(fd2, &c2, SIZE) == SIZE && errorbytes < 17){
for (int i=0 ; i < SIZE ; i++) {
if (c1[i] != c2[i] && cmpflag == 0){
printf("Bytes not matching at offset %d\n",numberofbytesread);
cmpflag = 1;
}
if (cmpflag == 1){
printf("Byte Output %d: 0x%02x 0x%02x\n", errorbytes, c1[i], c2[i]);
errorbytes++;
}
if (errorbytes > 16){
break;
}
numberofbytesread++;
}
}
}
int main(int argc, char *argv[])
{
int fd[2];
if (argc < 3){
printf("Check the number of arguments passed.\n");
printf("Usage: ./compare_binary <binaryfile1> <binaryfile2>\n");
exit(0);
}
if (!((access(argv[1], F_OK) == 0) && (access(argv[2], F_OK) == 0))){
printf("Please check if the files passed in the argument exist.\n");
exit(0);
}
fd[0] = open(argv[1], O_RDONLY);
fd[1] = open(argv[2], O_RDONLY);
if (fd[0]< 0 && fd[1] < 0){
printf("Can't open file.\n");
exit(0);
}
clock_t t;
t = clock();
compare_binary(fd[0], fd[1]);
t = clock() - t;
double time_taken = ((double)t)/(CLOCKS_PER_SEC/1000);
printf("compare_binary took %f milliseconds to execute \n", time_taken);
}
基本上需要优化的方式来读取超过1MB的二进制文件,这样它们可以在5毫秒内完成。
答案 0 :(得分:3)
首先,尝试阅读更大的块。当你可以一次阅读所有内容时,执行如此多的读取调用毫无意义。现在使用2 MB的内存并不是一件好事。磁盘I / O调用本身就很昂贵,它们的开销也很大,但可以减少。
其次,尝试在每次迭代中比较整数(甚至64位长)而不是字节,这样可以显着减少需要执行的循环次数。一旦找到错配,您仍然可以切换到每字节字节的实现。 (当然,如果文件长度不是4或8的倍数,则需要一些额外的技巧)。
答案 1 :(得分:0)
首先引起我注意的是这个
if (cmpflag == 1){
printf("Byte Output %d: 0x%02x 0x%02x\n", errorbytes, c1[i], c2[i]);
errorbytes++;
}
if (errorbytes > 16){
break;
}
你的cmpflag
检查没用,也许这件事做了一点点的反思
if (c1[i] != c2[i] && cmpflag == 0){
printf("Bytes not matching at offset %d\n",numberofbytesread);
printf("Byte Output %d: 0x%02x 0x%02x\n", errorbytes, c1[i], c2[i]);
errorbytes++;
if (errorbytes > 16){
break;
}
}
你可以做内置函数的数组比较,或者增加你的缓冲区