Linux C读写超大文件效率问题

xiaowhy 2011-08-24 07:16:20
各位高手帮忙看看,我这有几十G级别的比如60G文件需要读写,生成一些子文件,需要对原来文件的每一行进行解析;之前用fgets每一行的方法,客户对时间不是很满意;后来改用fork多个子进程,分段读取源文件,再生成不同的子文件,最后再把子文件合在一起,效果也不是很理想,逻辑不复杂,估计主要是IO的瓶颈;内存映射空间不够大吧,而且还要一行行的解析出来。
各位亲们不知有没有更好的办法啊?
...全文
2305 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 xiaowhy 的回复:]
现在是有把文件分成几段,分子进程去读写,生成几个临时文件,再合并,直接用系统命令CAT,就是在合并的时候,速度又太慢,40G的文件要10分钟左右
[/Quote]
40GB 读 + 40GB 写 = 80GB I/O,平均下来有 136.5MB/s。

如果用的是单块硬盘这速度都快暴表了……你还想闹那样……
worldy 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用楼主 xiaowhy 的回复:]
各位高手帮忙看看,我这有几十G级别的比如60G文件需要读写,生成一些子文件,需要对原来文件的每一行进行解析;之前用fgets每一行的方法,客户对时间不是很满意;后来改用fork多个子进程,分段读取源文件,再生成不同的子文件,最后再把子文件合在一起,效果也不是很理想,逻辑不复杂,估计主要是IO的瓶颈;内存映射空间不够大吧,而且还要一行行的解析出来。
各位亲们不知有没有更好的办法啊?
[/Quote]

文件以缓冲的形式打开,应该能有所改善,但是,60G实在是太大了,一行行fgets才是占用时间的关键,应该在这上面想办法优化
xiaowhy 2011-08-25
  • 打赏
  • 举报
回复
多进程写同一个文件的话,又要去加锁啥的,估计也很慢
xiaowhy 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 hgxxx007 的回复:]

给你个建议,用空间换时间。

你看看你地文本内容长度最大是多少,建议设定一个值:256或者128

然后如果每行不足256个字节,补足256字节。进行文件定位的时候直接seek到指定行。

如果内容不是简单的就知道行数,那么建议再创建一个外部索引,进行读写文件的时候只是先查看索引然后在进行读写文件指定位置。

如果你的需求更复杂一点,需要在中间插入和删除行。建议把大文件拆分成小文……
[/Quote]
现在是有把文件分成几段,分子进程去读写,生成几个临时文件,再合并,直接用系统命令CAT,就是在合并的时候,速度又太慢,40G的文件要10分钟左右
jackyjkchen 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hpsmouse 的回复:]

别急着优化程序,先算算现在的 I/O 速度是多少,要是已经达到了硬盘的速度上限程序再怎么优化都是白搭。

顺序读取大文件,内存映射其实没有直接读取快,不要碰到大文件就想着内存映射。
[/Quote]
至少对于Windows,内存映射的机制类似于异步IO,省去了同步等待ReadFile和WriteFile的时间,我做加密算法和Hash算法,处理大文件还是文件映射快
jngd 2011-08-25
  • 打赏
  • 举报
回复
你要知道你地程序读取的IO大部分都是废IO,

那就说明程序的优化空间或者架构优化空间还非常非常大。
jngd 2011-08-25
  • 打赏
  • 举报
回复
给你个建议,用空间换时间。

你看看你地文本内容长度最大是多少,建议设定一个值:256或者128

然后如果每行不足256个字节,补足256字节。进行文件定位的时候直接seek到指定行。

如果内容不是简单的就知道行数,那么建议再创建一个外部索引,进行读写文件的时候只是先查看索引然后在进行读写文件指定位置。

如果你的需求更复杂一点,需要在中间插入和删除行。建议把大文件拆分成小文件。然后外部任然通过一个索引文件进行索引。文件大小或者分片与否对上层不可见。
AnYidan 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hpsmouse 的回复:]
别急着优化程序,先算算现在的 I/O 速度是多少,要是已经达到了硬盘的速度上限程序再怎么优化都是白搭。

顺序读取大文件,内存映射其实没有直接读取快,不要碰到大文件就想着内存映射。
[/Quote]

硬件问题硬件解决
暮雨晨舟 2011-08-25
  • 打赏
  • 举报
回复
不懂,帮顶!
jackyjkchen 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 hpsmouse 的回复:]

引用 18 楼 jackyjkchen 的回复:
至少对于Windows,内存映射的机制类似于异步IO,省去了同步等待ReadFile和WriteFile的时间,我做加密算法和Hash算法,处理大文件还是文件映射快

内存映射也是等到缺页的时候才去读文件的吧?也是同步的才对。

刚刚在 Linux 下分别用 MD5 和每行的字符个数统计都试了一遍,内存映射比直接分块读取是要慢那么一点点……
[/Quote]

操作系统区别,Windows下内存映射优势很明显
csuhanyong 2011-08-25
  • 打赏
  • 举报
回复
可以利用分页的思想去读吧?先读取100行显示出来,在101到200行
mLee79 2011-08-25
  • 打赏
  • 举报
回复
mmap 就节约一次从内核空间到用户空间之间的拷贝, 其他速度上差别不大. 如果用 mmap 慢了就比较奇怪了.

这东西你还是优化优化处理过程吧, 要快的时候就 fread , fwrite , mmap 信得过. 这种东西瓶颈都在IO上, 多线程/进程没啥用的...
2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 jackyjkchen 的回复:]
至少对于Windows,内存映射的机制类似于异步IO,省去了同步等待ReadFile和WriteFile的时间,我做加密算法和Hash算法,处理大文件还是文件映射快
[/Quote]
内存映射也是等到缺页的时候才去读文件的吧?也是同步的才对。

刚刚在 Linux 下分别用 MD5 和每行的字符个数统计都试了一遍,内存映射比直接分块读取是要慢那么一点点,差距大概是几个 MB/s……
lamplet 2011-08-25
  • 打赏
  • 举报
回复
有一点现在都没弄明白,当时想通过setvbuf修改缓冲大小来提高效率,没有看到任何效果。后来改成每次读取大段内容却有效。不知道问题出在哪里。
lamplet 2011-08-25
  • 打赏
  • 举报
回复
我写过一个文件处理的程序,是顺序读取的。我不懂内存映射。只是自己把小段小段的读取,改成大段大段读取。减少文件读取次数,还是挺有效的。边界的问题,想办法处理下就好了。

不过,我也很想知道有什么经典的解决方法。老是做重复发明轮子的事情,浪费时间。还发明得比别人差,丢脸。
lightrat2009 2011-08-25
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 xiaowhy 的回复:]
引用 16 楼 hgxxx007 的回复:

给你个建议,用空间换时间。

你看看你地文本内容长度最大是多少,建议设定一个值:256或者128

然后如果每行不足256个字节,补足256字节。进行文件定位的时候直接seek到指定行。

如果内容不是简单的就知道行数,那么建议再创建一个外部索引,进行读写文件的时候只是先查看索引然后在进行读写文件指定位置。

如果你的需求更复杂一点……
[/Quote]硬盘的存储速度也就这么慢吧!!!
2011-08-24
  • 打赏
  • 举报
回复
别急着优化程序,先算算现在的 I/O 速度是多少,要是已经达到了硬盘的速度上限程序再怎么优化都是白搭。

顺序读取大文件,内存映射其实没有直接读取快,不要碰到大文件就想着内存映射。
xiaowhy 2011-08-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 aaajj 的回复:]

以前碰到过类似的问题,IO是很大的瓶颈。写文件的时候,可以设置个较大的缓存,减少写的次数
[/Quote]
这个我也有加啊,一般8K左右最好吧
aaajj 2011-08-24
  • 打赏
  • 举报
回复
以前碰到过类似的问题,IO是很大的瓶颈。写文件的时候,可以设置个较大的缓存,减少写的次数
jackyjkchen 2011-08-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mangsong 的回复:]

引用 5 楼 qq120848369 的回复:
你的问题是I/O瓶颈,这个与海量数据处理没啥关系.

如果给预处理时间的话,那可以读大文件哈希到若干小文件,每个小文件可以直接映射到内存处理,这样的话利用两个线程并发遍历所有的文件,效率会高不少了,因为I/O问题已经不存在了 =,=


我想问下,我碰到过一个问题,对一个文件做MD5校验,当时我是用malloc申请的内存一次性读进来所有……
[/Quote]
md5支持分割校验,前提是你得有基础算法

md5基础算法一般是三个函数
init
process
done
其中process可以执行多次
加载更多回复(7)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧