社区
C语言
帖子详情
Linux C读写超大文件效率问题
xiaowhy
2011-08-24 07:16:20
各位高手帮忙看看,我这有几十G级别的比如60G文件需要读写,生成一些子文件,需要对原来文件的每一行进行解析;之前用fgets每一行的方法,客户对时间不是很满意;后来改用fork多个子进程,分段读取源文件,再生成不同的子文件,最后再把子文件合在一起,效果也不是很理想,逻辑不复杂,估计主要是IO的瓶颈;内存映射空间不够大吧,而且还要一行行的解析出来。
各位亲们不知有没有更好的办法啊?
...全文
2398
27
打赏
收藏
Linux C读写超大文件效率问题
各位高手帮忙看看,我这有几十G级别的比如60G文件需要读写,生成一些子文件,需要对原来文件的每一行进行解析;之前用fgets每一行的方法,客户对时间不是很满意;后来改用fork多个子进程,分段读取源文件,再生成不同的子文件,最后再把子文件合在一起,效果也不是很理想,逻辑不复杂,估计主要是IO的瓶颈;内存映射空间不够大吧,而且还要一行行的解析出来。 各位亲们不知有没有更好的办法啊?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用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)
Linux
C大
文件
的创建和
读写
速率
在
Linux
环境下测试大
文件
(超过2G)的
读写
效率
Linux
下硬盘分区
读写
程序
自己学习C语言时写的一个小有规模的程序,请大家看看,提提意见。
【
Linux
文件
操作】深入解析
文件
指针:提升
文件
读写
效率
与灵活性的关键技术
内容概要:本文深入介绍了
Linux
文件
指针的概念及其在
文件
操作中的重要性。首先解释了
文件
指针的作用,类似于书签,帮助程序准确定位
文件
中的
读写
位置,极大提高了
文件
操作的
效率
和灵活性。接着详细描述了
文件
指针的基本定义和与
文件
描述符的关系,指出
文件
指针是C语言层面的概念,具有更高的可移植性和易用性。文章还详细讲解了
文件
指针的操作函数,包括打开与关闭
文件
(fopen、fclose)、基本
读写
操作(fread、fwrite)、格式化
读写
(fprintf、fscanf)、字符与字符串
读写
(fgetc、fputc、fgets、fputs)以及
文件
定位操作(fseek、ftell、rewind)。此外,文中探讨了
文件
指针在日志记录、数据库系统和进程间通信等应用场景中的具体应用。最后,强调了
文件
指针使用中的注意事项,如错误处理、缓冲区管理和内存泄漏
问题
,确保程序的稳定性和高效性。 适合人群:具备一定编程基础,特别是对C语言和
Linux
系统有一定了解的开发人员,尤其是从事
文件
处理、系统编程和数据库开发的工程师。 使用场景及目标:①理解和掌握
文件
指针的基本概念和操作方法;②在日志记录、数据库操作和进程间通信等场景中,高效地进行
文件
读写
操作;③通过合理的错误处理、缓冲区管理和内存管理,编写更健壮、高效的程序。 阅读建议:读者应结合实际编程案例,深入理解
文件
指针的工作原理和应用场景。建议在学习过程中多做实验,熟悉各种
文件
操作函数的使用方法,并注意错误处理和资源管理,以提升编程技能和解决实际
问题
的能力。
Linux
内核源代码情景分析 (上下册 高清非扫描 )
本PDF电子书包含上下两册,共1576页,带目录,高清非扫描版本。 作者: 毛德操 胡希明 丛书名:
Linux
内核源代码情景分析 出版社:浙江大学出版社 目录 第1章 预备知识 1.1
Linux
内核简介. 1.2 Intel X86 CPU系列的寻址方式 1.3 i386的页式内存管理机制 1.4
Linux
内核源代码中的C语言代码 1.5
Linux
内核源代码中的汇编语言代码 第2章 存储管理 2.1
Linux
内存管理的基本框架 2.2 地址映射的全过程 2.3 几个重要的数据结构和函数 2.4 越界访问 2.5 用户堆栈的扩展 2.6 物理页面的使用和周转 2.7 物理页面的分配 2.8 页面的定期换出 2.9 页面的换入 2.10 内核缓冲区的管理 2.11 外部设备存储空间的地址映射 2.12 系统调用brk() 2.13 系统调用mmap() 第3章 中断、异常和系统调用 3.1 X86 CPU对中断的硬件支持 3.2 中断向量表IDT的初始化 3.3 中断请求队列的初始化 3.4 中断的响应和服务 3.5 软中断与Bottom Half 3.6 页面异常的进入和返回 3.7 时钟中断 3.8 系统调用 3.9 系统调用号与跳转表 第4章 进程与进程调度 4.1 进程四要素 4.2 进程三部曲:创建、执行与消亡 4.3 系统调用fork()、vfork()与clone() 4.4 系统调用execve() 4.5 系统调用exit()与wait4() 4.6 进程的调度与切换 4.7 强制性调度 4.8 系统调用nanosleep()和pause() 4.9 内核中的互斥操作 第5章
文件
系统 5.1 概述 5.2 从路径名到目标节点 5.3 访问权限与
文件
安全性 5.4
文件
系统的安装和拆卸 5.5
文件
的打开与关闭 5.6
文件
的写与读 5.7 其他
文件
操作 5.8 特殊
文件
系统/proc 第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6.5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 第7章基于socket的进程间通信 7.1系统调用socket() 7.2函数sys—socket()——创建插口 7.3函数sys—bind()——指定插口地址 7.4函数sys—listen()——设定server插口 7.5函数sys—accept()——接受连接请求 7.6函数sys—connect()——请求连接 7.7报文的接收与发送 7.8插口的关闭 7.9其他 第8章设备驱动 8.1概述 8.2系统调用mknod() 8.3可安装模块 8.4PCI总线 8.5块设备的驱动 8.6字符设备驱动概述 8.7终端设备与汉字信息处理 8.8控制台的驱动 8.9通用串行外部总线USB 8.10系统调用select()以及异步输入/输出 8.11设备
文件
系统devfs 第9章多处理器SMP系统结构 9.1概述 9.2SMP结构中的互斥
问题
9.3高速缓存与内存的一致性 9.4SMP结构中的中断机制 9.5SMP结构中的进程调度 9.6SMP系统的引导 第10章系统引导和初始化 10.1系统引导过程概述 10.2系统初始化(第一阶段) 10.3系统初始化(第二阶段) 10.4系统初始化(第三阶段) 10.5系统的关闭和重引导
Linux
读写
文件
学习了
文件
系统,就能理解为什么说
Linux
下一切皆
文件
。在c语言的学习中我们可以使用fopen()函数对
文件
进行操作。FILE在c语言上是一个结构体,包含了
文件
操作的基本属性,对
文件
的操作都要通过这个结构的指针来进行。上面提到的这些函数都是库函数,而像open()、close()、read()、write()都是属于系统提供的接口。
C语言
70,022
社区成员
243,263
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章