如何快速的实现大小为3G的txt文件的读取和处理

C++语言 码拜 9年前 (2015-05-11) 2048次浏览 0个评论

LZ学生党,有个问题想请教大家:
现在需要处理一个9万行,每行2001个浮点数的txt文件,大小约为3G。
需要进行的处理是:对每一行的后2000个数字进行从大到小排序。
我现在用的办法是:用ifstream进行读取,读出一行后存在一个vector<float>中,然后用快速排序进行处理。然后再读一行,再处理。但是我这样完成全部9万行的排序需要大约1到2分钟。

因为我的整个流程中需要执行约30万次的排序操作,每次会有一个在程序中生成的不同的2000维的浮点数向量,然后9万*2000的矩阵的每一列乘以对应的2000维向量中的一个数然后再分别每一行进行排序。
假如按照我之前的方法,每次读入一行,然后再乘以2000维向量对应的数后再排序,那么30万次需要的时间太长了。

我想向大家请教一下,我整个流程中最耗时的是不是读取文件的IO操作?我应该如何改善呢?

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?
引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

不是,每行第一个数字是另外的用途,比如第一个数子是500.0,那么我需要找到原始顺序中第500个数在排序完成后的序列中的位置。
不用写回原文件,我只需要排序来得到一些结果就行了。

引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

引用 3 楼 zxczxcvvvvv 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

3G的文件是可以一次性读入的,但在Win32下不行

引用 4 楼 zhangxiangDavaid 的回复:
Quote: 引用 3 楼 zxczxcvvvvv 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

3G的文件是可以一次性读入的,但在Win32下不行

我按一个float 4个字节算,9万行*每行2001个,这样算下来内寸肯定放不下,用什么方法可以读入呢?

引用 5 楼 zxczxcvvvvv 的回复:
Quote: 引用 4 楼 zhangxiangDavaid 的回复:
Quote: 引用 3 楼 zxczxcvvvvv 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

3G的文件是可以一次性读入的,但在Win32下不行

我按一个float 4个字节算,9万行*每行2001个,这样算下来内寸肯定放不下,用什么方法可以读入呢?

只要你的电脑内存足够就行,vs下x64,可以申请足够内存

引用 6 楼 zhangxiangDavaid 的回复:
Quote: 引用 5 楼 zxczxcvvvvv 的回复:
Quote: 引用 4 楼 zhangxiangDavaid 的回复:
Quote: 引用 3 楼 zxczxcvvvvv 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

3G的文件是可以一次性读入的,但在Win32下不行

我按一个float 4个字节算,9万行*每行2001个,这样算下来内寸肯定放不下,用什么方法可以读入呢?

只要你的电脑内存足够就行,vs下x64,可以申请足够内存

我计算了一下,需要600多G的内存,这个是不是太大了

引用 7 楼 zxczxcvvvvv 的回复:
Quote: 引用 6 楼 zhangxiangDavaid 的回复:
Quote: 引用 5 楼 zxczxcvvvvv 的回复:
Quote: 引用 4 楼 zhangxiangDavaid 的回复:
Quote: 引用 3 楼 zxczxcvvvvv 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

3G的文件是可以一次性读入的,但在Win32下不行

我按一个float 4个字节算,9万行*每行2001个,这样算下来内寸肯定放不下,用什么方法可以读入呢?

只要你的电脑内存足够就行,vs下x64,可以申请足够内存

我计算了一下,需要600多G的内存,这个是不是太大了

你怎么算的,不是才3G的文件吗

引用 8 楼 zhangxiangDavaid 的回复:
Quote: 引用 7 楼 zxczxcvvvvv 的回复:
Quote: 引用 6 楼 zhangxiangDavaid 的回复:
Quote: 引用 5 楼 zxczxcvvvvv 的回复:
Quote: 引用 4 楼 zhangxiangDavaid 的回复:
Quote: 引用 3 楼 zxczxcvvvvv 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

每一行的第一个数字是行号吗?每行排序后,需要写回原文件吗?

我想能不能一次性都读进内存,这样读一次就够了,但是我算了一下好像太大了,没办法读进来。

3G的文件是可以一次性读入的,但在Win32下不行

我按一个float 4个字节算,9万行*每行2001个,这样算下来内寸肯定放不下,用什么方法可以读入呢?

只要你的电脑内存足够就行,vs下x64,可以申请足够内存

我计算了一下,需要600多G的内存,这个是不是太大了

你怎么算的,不是才3G的文件吗

txt文件是3G,但是读进数组里的话,如果一个浮点数算4B,那一共有(90000*2001*4)/(1024*1024)=600多 G,是不是不应该这么算? 

30分
90000*2001*4=720360000 Byte
720360000/1024=703476.5625 KB
703476.5625 /1024=686.988830 MB
引用 10 楼 zhangxiangDavaid 的回复:

90000*2001*4=720360000 Byte
720360000/1024=703476.5625 KB
703476.5625 /1024=686.988830 MB

不好意思搞错了
多谢您的指正,我还有一个问题,就是像我这样的流程,最花费时间的过程是不是IO的过程呢?

引用 11 楼 zxczxcvvvvv 的回复:
Quote: 引用 10 楼 zhangxiangDavaid 的回复:

90000*2001*4=720360000 Byte
720360000/1024=703476.5625 KB
703476.5625 /1024=686.988830 MB

不好意思搞错了
多谢您的指正,我还有一个问题,就是像我这样的流程,最花费时间的过程是不是IO的过程呢?

我没具体的数据不好说,你可以分别测试下读入时间和排序时间

引用 12 楼 zhangxiangDavaid 的回复:
Quote: 引用 11 楼 zxczxcvvvvv 的回复:
Quote: 引用 10 楼 zhangxiangDavaid 的回复:

90000*2001*4=720360000 Byte
720360000/1024=703476.5625 KB
703476.5625 /1024=686.988830 MB

不好意思搞错了
多谢您的指正,我还有一个问题,就是像我这样的流程,最花费时间的过程是不是IO的过程呢?

我没具体的数据不好说,你可以分别测试下读入时间和排序时间

在排序这块,我是在vector内使用的快速排序,请问这里可以使用什么方法改进一下时间吗?

一般情况下,首先快排,似乎没有更快的了……
引用 14 楼 zhangxiangDavaid 的回复:

一般情况下,首先快排,似乎没有更快的了……

好的,谢谢您,有问题的话再向您请教

10分
为什么不放数据库里面加索引呢?

<1000个元素,冒泡排序
<100000个元素,qsort函数
<10000000个元素,放数据库中,建索引,(B+树排序)
≥10000000个元素,没用到过。

mmap,数据库确实是最优选择
引用 16 楼 zhao4zhong1 的回复:

为什么不放数据库里面加索引呢?

<1000个元素,冒泡排序
<100000个元素,qsort函数
<10000000个元素,放数据库中,建索引,(B+树排序)
≥10000000个元素,没用到过。

请问这里指的元素就是数据库中的一行吗?为什么这种情况下用数据库最好呢?

5分
这种事情,交给数据库去做是最合理的。
也许不是最快,但是够快。关键是够可靠。
就说你考虑下断电保护,你自己写代码就别玩了。
5分
不用文件,3g 数据直接放在内存里就行了。
另外,如果向量总是右乘矩阵,把矩阵按照列主元格式放在内存里。
还有,最好先实测一下,到底慢在哪里了。
搜“B+树排序”
https://www.baidu.com/s?wd=B%2B%E6%A0%91%E6%8E%92%E5%BA%8F&rsv_spt=1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=2&rsv_sug1=1&rsv_n=2

 https://passport.csdn.net/account/login?username=z13975112990&activeCode=e3cfbb2da10056037aa96cdeaa9f9551&service=https://passport.csdn.net/account/register?action=userInfoView
感觉好难哦………………………………….

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明如何快速的实现大小为3G的txt文件的读取和处理
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!