123.34 ,234.56,456.67,15
223.34 ,234.56,456.67,15
。。。。。。。
如何快速读取这个文件,我读取要500W行要一分钟时间,太慢了 有没有更好办法
GetSysTime(_T("开始测试2:"));
vector<pnode> list2;
string Fname="D:\\点集合\\tt500.txt";
FILE * fp=fopen(Fname.c_str(),"rb+");
if(fp==NULL)
{
MessageBox(NULL,_T("aa"),_T("文件打开失败"),0);
return;
}
while(!feof(fp))
{
pnode nd;
fscanf(fp,"%Lf,%Lf,%Lf,%Lf\n",&nd.x,&nd.y,&nd.z,&nd.i);
//list2.push_back(nd);
}
fclose(fp);
GetSysTime(_T("结束测试2:"));
18 个解决方案
#1
创建内存映射空间,一次读取内存中再处理,如果要用多线程,可以将数据平等分割,判断取出首条数据,然后再在多线程中出现
#2
直接多开几个线程,并发读取就好了
#3
GetSysTime(_T("开始测试3:"));
FILE *fp=fopen("D:\\点\\tt500.txt","rb+");
char line[256]={0};
while(fgets(line,255,fp))
{
pnode nd;
sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
double xx=nd.x;
double yy=nd.y;
double zz=nd.z;
}
fclose(fp);
GetSysTime(_T("开始测试3:"));
经过测试此次需要35s,但是如果不处理读取的数据,即注释掉
//sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
// double xx=nd.x;
// double yy=nd.y;
// double zz=nd.z;
只需要1.4s
关键是如何提高sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);的效率
有没有更好的办法将line 转化为结构体?
#4
一次行load到内存吧
#5
一个建议方案:
不用fopen/fscanf这些,而用操作系统的API直接进行;
数据记录定长吗?不定长想办法改成定长(比如补空格),然后每次加载定量的数据行,不是一行,是N行,进内存后再解析
N的取值你根据你测试的结果选一个合适的
我实在想象不出为什么几百万行的数据居然还是用不定长文本进行存储
以上方案如果还不能满足性能,那就把文本化的浮点数改为二进制存储
不用fopen/fscanf这些,而用操作系统的API直接进行;
数据记录定长吗?不定长想办法改成定长(比如补空格),然后每次加载定量的数据行,不是一行,是N行,进内存后再解析
N的取值你根据你测试的结果选一个合适的
我实在想象不出为什么几百万行的数据居然还是用不定长文本进行存储
以上方案如果还不能满足性能,那就把文本化的浮点数改为二进制存储
#6
建议以二进制的形式存储,少一个sscanf的过程。
还有一个问题是,你将下面的这些注释后,
//sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
// double xx=nd.x;
// double yy=nd.y;
// double zz=nd.z;
要注意这个测试的1.4s的可靠性,我怀疑这个1.4s的准确度,因为你将这些注释掉,那么就是循环中没有做任何的操作,导致有可能编译器做了优化。可以反汇编看一下。是否开了o2优化选项?
pnode nd;,double xx 这些也要放到循环外面去定义,不要放在循环内。
还有一个问题是,你将下面的这些注释后,
//sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
// double xx=nd.x;
// double yy=nd.y;
// double zz=nd.z;
要注意这个测试的1.4s的可靠性,我怀疑这个1.4s的准确度,因为你将这些注释掉,那么就是循环中没有做任何的操作,导致有可能编译器做了优化。可以反汇编看一下。是否开了o2优化选项?
pnode nd;,double xx 这些也要放到循环外面去定义,不要放在循环内。
#7
读取这么大的文件才需要1分钟,这有什么好嫌慢的。你再优化,提高也有限的。
阐述你的原始需求,才可能得到正确的解。
阐述你的原始需求,才可能得到正确的解。
#8
1. 如果是机械硬盘,开多线程反而慢
2. 500w也就5M,一行算100个字符也可以接受(Windows),所以先全读内存里
2. 500w也就5M,一行算100个字符也可以接受(Windows),所以先全读内存里
#9
试试把文件流的buf调大点, 每次scanf多行
#10
每天都有人提出用多线程读写磁盘的馊主意。
#11
mark一下,不错的帖子,我觉的慢主要慢在处理吧,5M的数据不大的,我觉的你可以把数据都读如数组,然后处理的时候多个线程进行处理吧
#12
正解!磁盘是没办法做到那种并发的,呵呵
不过这里倒是可以考虑解析的时候起几个线程来,按照楼主描述,他好像解析时间跟不上
#13
1.4s倒是可以认为是可靠的,我用的是“反证法”,如果说编译器优化掉读文件的代码,那么你重新看一下整个程序,
基本上没有什么操作,根本用不了1.4s的执行时间,所以说优化掉读文件是不存在的情况
#14
不会是搞什么大数据,或者量化金融之类的吧
#15
唯一的办法是一次读取1-10M的内容,然后再提取,如果每次读一个,硬盘次数太多,速度也就慢了,500万行,50M的样子,每次读5M,10次就可以读完,读完后,提取计算的时间会很少,所以你这个过程大概5s内完成
#16
在文件大小相同的前提下:
读刚读过的文件比头次读没读过的文件快
读转速快的硬盘上的文件比读转速慢的硬盘上的文件快
读没有磁盘碎片的文件比读有磁盘碎片的文件快
读文件不处理比边读边处理快
单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
读固态硬盘上的文件比读普通硬盘上的文件快
读刚读过的文件比头次读没读过的文件快
读转速快的硬盘上的文件比读转速慢的硬盘上的文件快
读没有磁盘碎片的文件比读有磁盘碎片的文件快
读文件不处理比边读边处理快
单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
读固态硬盘上的文件比读普通硬盘上的文件快
#17
首先全部到内存,内存处理快,然后再每行到一个固定的结构体。memcpy(struct,fread_line,sizeof(fread_line));
或者,使用多线程(前提是使用的多核处理器),每个线程分别处理一块。
#18
您是否希望迅速对您频繁使用的文件进行碎片整理?使用 Contig 优化单个的文件,或者创建连续的新文件。
http://technet.microsoft.com/zh-cn/sysinternals/bb897428
#1
创建内存映射空间,一次读取内存中再处理,如果要用多线程,可以将数据平等分割,判断取出首条数据,然后再在多线程中出现
#2
直接多开几个线程,并发读取就好了
#3
GetSysTime(_T("开始测试3:"));
FILE *fp=fopen("D:\\点\\tt500.txt","rb+");
char line[256]={0};
while(fgets(line,255,fp))
{
pnode nd;
sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
double xx=nd.x;
double yy=nd.y;
double zz=nd.z;
}
fclose(fp);
GetSysTime(_T("开始测试3:"));
经过测试此次需要35s,但是如果不处理读取的数据,即注释掉
//sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
// double xx=nd.x;
// double yy=nd.y;
// double zz=nd.z;
只需要1.4s
关键是如何提高sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);的效率
有没有更好的办法将line 转化为结构体?
#4
一次行load到内存吧
#5
一个建议方案:
不用fopen/fscanf这些,而用操作系统的API直接进行;
数据记录定长吗?不定长想办法改成定长(比如补空格),然后每次加载定量的数据行,不是一行,是N行,进内存后再解析
N的取值你根据你测试的结果选一个合适的
我实在想象不出为什么几百万行的数据居然还是用不定长文本进行存储
以上方案如果还不能满足性能,那就把文本化的浮点数改为二进制存储
不用fopen/fscanf这些,而用操作系统的API直接进行;
数据记录定长吗?不定长想办法改成定长(比如补空格),然后每次加载定量的数据行,不是一行,是N行,进内存后再解析
N的取值你根据你测试的结果选一个合适的
我实在想象不出为什么几百万行的数据居然还是用不定长文本进行存储
以上方案如果还不能满足性能,那就把文本化的浮点数改为二进制存储
#6
建议以二进制的形式存储,少一个sscanf的过程。
还有一个问题是,你将下面的这些注释后,
//sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
// double xx=nd.x;
// double yy=nd.y;
// double zz=nd.z;
要注意这个测试的1.4s的可靠性,我怀疑这个1.4s的准确度,因为你将这些注释掉,那么就是循环中没有做任何的操作,导致有可能编译器做了优化。可以反汇编看一下。是否开了o2优化选项?
pnode nd;,double xx 这些也要放到循环外面去定义,不要放在循环内。
还有一个问题是,你将下面的这些注释后,
//sscanf(line,"%lf,%lf,%lf,",&nd.x,&nd.y,&nd.z);
// double xx=nd.x;
// double yy=nd.y;
// double zz=nd.z;
要注意这个测试的1.4s的可靠性,我怀疑这个1.4s的准确度,因为你将这些注释掉,那么就是循环中没有做任何的操作,导致有可能编译器做了优化。可以反汇编看一下。是否开了o2优化选项?
pnode nd;,double xx 这些也要放到循环外面去定义,不要放在循环内。
#7
读取这么大的文件才需要1分钟,这有什么好嫌慢的。你再优化,提高也有限的。
阐述你的原始需求,才可能得到正确的解。
阐述你的原始需求,才可能得到正确的解。
#8
1. 如果是机械硬盘,开多线程反而慢
2. 500w也就5M,一行算100个字符也可以接受(Windows),所以先全读内存里
2. 500w也就5M,一行算100个字符也可以接受(Windows),所以先全读内存里
#9
试试把文件流的buf调大点, 每次scanf多行
#10
每天都有人提出用多线程读写磁盘的馊主意。
#11
mark一下,不错的帖子,我觉的慢主要慢在处理吧,5M的数据不大的,我觉的你可以把数据都读如数组,然后处理的时候多个线程进行处理吧
#12
正解!磁盘是没办法做到那种并发的,呵呵
不过这里倒是可以考虑解析的时候起几个线程来,按照楼主描述,他好像解析时间跟不上
#13
1.4s倒是可以认为是可靠的,我用的是“反证法”,如果说编译器优化掉读文件的代码,那么你重新看一下整个程序,
基本上没有什么操作,根本用不了1.4s的执行时间,所以说优化掉读文件是不存在的情况
#14
不会是搞什么大数据,或者量化金融之类的吧
#15
唯一的办法是一次读取1-10M的内容,然后再提取,如果每次读一个,硬盘次数太多,速度也就慢了,500万行,50M的样子,每次读5M,10次就可以读完,读完后,提取计算的时间会很少,所以你这个过程大概5s内完成
#16
在文件大小相同的前提下:
读刚读过的文件比头次读没读过的文件快
读转速快的硬盘上的文件比读转速慢的硬盘上的文件快
读没有磁盘碎片的文件比读有磁盘碎片的文件快
读文件不处理比边读边处理快
单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
读固态硬盘上的文件比读普通硬盘上的文件快
读刚读过的文件比头次读没读过的文件快
读转速快的硬盘上的文件比读转速慢的硬盘上的文件快
读没有磁盘碎片的文件比读有磁盘碎片的文件快
读文件不处理比边读边处理快
单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
读固态硬盘上的文件比读普通硬盘上的文件快
#17
首先全部到内存,内存处理快,然后再每行到一个固定的结构体。memcpy(struct,fread_line,sizeof(fread_line));
或者,使用多线程(前提是使用的多核处理器),每个线程分别处理一块。
#18
您是否希望迅速对您频繁使用的文件进行碎片整理?使用 Contig 优化单个的文件,或者创建连续的新文件。
http://technet.microsoft.com/zh-cn/sysinternals/bb897428