【问题标题】:Difference results with mmap (c), fopen(c) and ifstream(c++)mmap (c)、fopen(c) 和 ifstream(c++) 的差异结果
【发布时间】:2021-01-01 14:44:54
【问题描述】:

我有 3 个不同的程序(mmap、fopen、ifstream)来计算文件中字符的出现次数。我这样做是为了测试从内存读取文件的不同技术的性能。但即使我得到相同的 ifstream 和 fopen 计数,mmap 给出的计数比其他两个更高,我无法检测到原因。

如果流:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <time.h>

using namespace std;

int main(){

printf("\n");

clock_t begin = clock();

ifstream file;
string filename = "loremipsum.txt";
file.open(filename.c_str());


char ch;
int count = 0;

while(file.get(ch)){

    if(ch == 'a'){
        count++;
    }
}

clock_t end = clock();



double time_spent = 0.0;
time_spent += (double)(end - begin) / CLOCKS_PER_SEC;

cout << "Number of 'a' in file: " << count << endl;
cout << "Time elapsed for counting: " << time_spent << endl;

printf("\n");

return 0;
}

打开:

#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
#include <sys/stat.h>
#include <fcntl.h>


int main(void)
{
printf("\n");

FILE *fp;
int id;
char ch;
double time_spent = 0.0;
int count = 0;

clock_t begin = clock();
if ((fp = fopen ("loremipsum.txt", "r")) == NULL) {
    printf("Dosya açma hatası!");
    exit(1);
}

ch = fgetc ( fp ) ;



while(ch != EOF){

  
    if(ch == 'a'){
        count += 1;
    }

    ch = fgetc ( fp ) ;
}

clock_t end = clock();






time_spent += (double)(end - begin) / CLOCKS_PER_SEC;

printf("Time elapsed is %f seconds\n", time_spent);

printf("number of character 'a' is %d\n", count);
fclose(fp);

printf("\n");
return 0;
}

mmap:

#include <iostream>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h> 
#include <unistd.h>


int main(void){


int fd = open ("loremipsum.txt", O_RDONLY);
struct stat s;
size_t size;
int status = fstat(fd, &s);
size = s.st_size;
double time_spent = 0.0;

clock_t begin = clock();

char *ptr = (char*) mmap(0,size,PROT_READ,MAP_PRIVATE,fd,0);

if(ptr == MAP_FAILED){

    printf("Mapping failed\n");
    return 1;
}



int i = 0, count = 0;
while(ptr[i] != EOF){
    if(ptr[i] == 'a'){
        count++;
    }
    i++;
}

clock_t end = clock();


printf("\nnumber of a is %d\n", count);

time_spent += (double)(end - begin) / CLOCKS_PER_SEC;

printf("Time elapsed is %f seconds\n", time_spent);


status = munmap(ptr, size);

if(status != 0){
    
    printf("Unmapping failed\n");
    return 1;
}
close(fd);

printf("\n");
return 0;


}

【问题讨论】:

    标签: c++ c mmap


    【解决方案1】:

    在 mmap 版本中,ptr[i] != EOF 检查看起来非常可疑,应该将循环更改为 for-loop,该循环始终精确地迭代 size 次,因为 ptr[i] 可以合法地是任何字节值,并且有它不可能发出EOF的信号。

    【讨论】:

    • 非常感谢!我认为它也会将 EOF 获取到缓冲区,但事实并非如此。现在完美运行。
    猜你喜欢
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多