您的位置:首页 > 其它

在ubuntu下生成大文件,并测试文件读写效率

2010-05-23 21:40 471 查看
在ubuntu或者其他的linux下生成大文件,必须使用编译参数-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64.否则生成的文件一定是2G左右的,原因是fseek,这个函数中的offset参数是一个long型的或者是size_t型的,在fseeko中是off_t,但是这个off_t默认还是32位,只有加了

-D_FILE_OFFSET_BITS=64的宏定义才被作为64位对待.

 

写了下面一段代码来生成大文件,传说有一种方法:直接跳转nG位置之后,然后写入一个字符.这种方法可能更快,不过我为了保守的生成文件,还是使用下面的一个写法:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
void gen_file(const char *filename, int block_size, int count){
int is_exist = 0;
FILE* file = fopen(filename,"w+b");
char * buf = NULL;
int i=0;
long long size = block_size;
if(file == NULL){
printf("fatal error in gen_file: fopen/n");
exit(1);
}
buf = (char *)malloc(sizeof(char)*block_size);
memset(buf,'1',sizeof(char)*block_size);
while(i++<count){
if(i % 10 == 0){
printf("count is %d, size is %lld/n",i,size);
}
fwrite(buf,block_size,1,file);
size += block_size;
fseeko(file,size,SEEK_SET);
}
fclose(file);
free(buf);
/*	long long size = 1024*1024*1024;
size *=10;
fseeko(file,size,SEEK_SET);
fwrite(buf,block_size,1,file);
fclose(file);
free(buf);
*/
}
int main(){
printf("size of char %d/n",sizeof(char));
int block_size = 1024*1024*20; // 20M
int count = 50;
gen_file("smallfile",block_size,count*2);// gen 2G file

return 0;
}


int block_size = 1024*1024*20; // 20M

这个是每次写入的数据大小,gen_file("smallfile",block_size,count*2);第三个参数可以调节生成文件的大小.

下面写了一个测试大文件和小文件的随机读写和顺序读写.

#include<stdio.h>
#include<time.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/time.h>
#include<string.h>
const int block_size = 8092;
struct timeval start;
struct timeval end;
struct timezone tz;
void start_time(){
gettimeofday(&start,&tz);
}
void end_time(){
gettimeofday(&end,&tz);
}
void print_time(){
printf("%lf sec/n",(end.tv_sec-start.tv_sec)+(double)(end.tv_usec-start.tv_usec)/1000000);
}
size_t look_size(const char * filename){
struct stat st;
stat(filename,&st);
return st.st_size;
}
void read_blocks(FILE* file, off_t offset,int block_size){
int where = offset*block_size;
fseeko(file,where,0);

}
FILE* fopen_safe(const char * filename){
FILE* file = fopen(filename,"r");
if(file == NULL){
printf("fatal error in random_read, open file");
exit(1);
}
return file;
}
void random_read(const char * filename){
int random;
size_t size;
FILE* file = fopen_safe(filename);
size = look_size(filename)/block_size;
random = rand()%size;
read_blocks(file,random,block_size);
fclose(file);
}
void order_read(const char *filename,int order){
size_t size;
FILE* file = fopen_safe(filename);
size = look_size(filename)/block_size;
read_blocks(file,order%size,block_size);
fclose(file);
}
void random_test(const char * filename,int times){
int count = 0;
start_time();
while(count++<times){
// access Big File
random_read(filename);
}
end_time();
print_time();
}
void order_test(const char * filename, int times){
int count = 0;
start_time();
while(count++<times){
order_read(filename,count);
}
end_time();
print_time();
}
void random_test_diff(const char * basename,int num,int times){
int count = 0;
char ** names = malloc(sizeof(char)*num);
int len = strlen(basename);
int i = 0;
while( i < num){
names[i] = malloc(sizeof(char)*len+4);
sprintf(names[i],"%s_%d",basename,i);
i++;
}
start_time();
while(count++<times){
if(count < 900){
random_read(names[0]);
}
else {
if(count < 960){
random_read(names[count%num]);
random_read(names[(count+1)%num]);
}
if(count < 1000){
random_read(names[count%num]);
random_read(names[(count+1)%num]);
random_read(names[(count+2)%num]);
}
}
}
end_time();
print_time();
}
int main(){
int i,count;
int times = 1000;
count = 0;
//	clock_t start,end;
srand(time(NULL));
char * filename="bigfile";
//printf("time is %lf",((double)(end-start))/CLOCKS_PER_SEC);
random_test(filename,times);
order_test(filename,times);
times = times;
filename = "smallfile";

random_test(filename,times);
order_test(filename,times);

random_test_diff(filename,3,times);
return 0;
}


当然你这里做测试的时候可以把gettimeofday替换为clock()或者time()函数,其中clock()是程序实际运行的时间,你感觉可能执行了七八秒,其实程序只占用cpu执行了1秒.如果是time()函数或者gettimeofday()函数就是真正的运行时间也就是你感觉执行的时间.所以各有千秋,前者是为了排除各种运行环境中的软件或者os的不同,单独检测程序的效率.后者是在系统环境中程序的执行时间.

下面是我得到的结论,创建1个10G文件,创建3个2G小文件.

大文件 随机访问7.199645 sec

大文件 顺序访问0.013617 sec

单个小文件 随机访问5.119245 sec

小文件 顺序访问0.014190 sec

多个小文件的随机访问测试:90%的几率访问同一个小文件,6%访问两个小文件,4%访问3个小文件 9.791248 sec.并且90%几率发生在前,所以如果随机发生多个文件的随机访问,那么可能速度会更慢.这里慢的原因,是因为fopen.

这也就是数据库为什么只有一个数据文件的原因.有时进行文件切分,反而不利于效率的提高.但是对于100G以上的大文件,是否这个结论又要改变了呢?我没有做过这个实验.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息