较大数据文件的读取优化过程续
来源:互联网 发布:apache ignite 编辑:程序博客网 时间:2024/05/17 22:54
由来
在上一篇博客(见参考1)中写了从基本到优化的过程,但仍然有可以优化的余地,这里记录下。
问题
文章1中根据固定行字节数优化读取速度有很大的弊端,就是需要解析的文件可能是不规则行长度的。可以有通用的按行解析的方法。当然前提仍然是基于内存映射文件。这里操作一个dat文件,共分n段,数据以空格分隔,行以\r\n
分隔,大部分段平均每行大约10个双精度浮点数,小部分整数。共180w行,300MB大小。
char*+sscanf
方法
首先想到的是c的速度快,直接操作指针应该速度不错。
那么主要方法就是查找换行符,和前一个换行符组成当前行字符串,再用sscanf
分解到double d[10]
数组里去。
结果是:release下19S读完。
char*+strtok_s
方法
继续优化,sscanf
及sscanf_s
都是可变参数函数模板,一定效率比较低,换成 strtok_s
。
主要方法是先查找换行符,和前一个换行符组成当前行字符串,再用strtok_s
分隔行字符串到double d[10]
数组里去。
结果是:release下16S读完。
stdstring+strtok_s
方法
继续优化,上面的设想都是认为c肯定比c++快,但真的这样吗?尝试的态度下用了string
做行分隔,结果却证明这种情况下string
比char*
快。
主要方法是得到内存映射文件指针后,直接用这个指针构造string
长字符串,然后对这个字符串用find('\n')
来分隔行,再按上面的方法用strtok_s
分隔具体的数组。
结果是:release下7.9s读完。很大的提升了,可见思维定势不能有啊,c++一样可以快。
多线程 +stdstring+strtok_s
方法
还能继续优化吗?
从上面的方法可以看到,一开始整个文件已经转为字符串在内存里了,虽然不能用多线程直接读文件,但用多线程读内存是可以的!
主要方法是这样:先遍历一遍全部字符串,找出每段开头的偏移量,记录下来,然后开线程,在线程函数里,传入这个偏移量,解析即可。
结果是:4.4s读完。
注意:开线程的数量应该是有讲究的,我是选择和cpu线程数相同,不同的时候经过测试,不如相同
继续优化?
还能继续优化吗?或许c++17并行库可以
参考文献
1.较大数据文件的读取优化过程
- 较大数据文件的读取优化过程续
- 较大数据文件的读取优化过程
- python 数据文件的读取
- pandas分块读取较大csv的方法
- 数据文件的存储和读取
- drad 读取优化过程
- 读取数据文件
- 如何用VB.net快速读取较大的xml文件
- 可以读取较大的图片而不会内存溢出了
- aSP读取XML数据文件的方法
- ASP读取XML数据文件的方法
- matlab读取二进制数据文件的方法
- gnuplot 读取逗号分隔的数据文件
- VB读取超过2G的数据文件
- Android NDK下读取数据文件的方法
- R语言-json数据文件的批量读取
- gnuplot 读取逗号分隔的数据文件
- 读取Aster库的.sli数据文件
- Java NIO Scatter / Gather
- SublimeText 3 packagecontrol installation#st3
- 将yuv转成png图
- openfire 成功安装后无法启动,无法访问http://ip:9090
- 一行代码解决ie浏览器弹出允许阻止控件问题
- 较大数据文件的读取优化过程续
- Error found when loading /root/.profile错误
- Linux常用操作
- DTD文档的阅读和编写——web.xml报错不要再百度了
- java批量删除redis中以某字符串前缀的key
- Linux下高性能网络编程中的几个TCP/IP选项
- redis-server python
- 第五周 项目三-时间类(1)
- BZOJ4403: 序列统计