【发布时间】:2017-01-04 22:01:42
【问题描述】:
我希望从大型(~870,000,000 行/~4GB)文本文件中提取某些行组。举个小例子,在一个 50 行的文件中,我可能需要第 3-6、18-27 和 39-45 行。使用 SO 开始,并编写一些程序来对我的数据进行基准测试,似乎 fortran90 给了我最好的结果(与 python、shell 命令(bash)等相比)。
我当前的方案只是打开文件并使用一系列循环将读取指针移动到我需要的位置并将结果写入输出文件。
使用上面的小例子,它看起来像:
open(unit=1,fileName)
open(unit=2,outFile)
do i=1,2
read(1,*)
end do
do i=3,6
read(1,*) line
write(2,*) line
end do
do i=7,17
read(1,*)
end do
do i=18,27
read(1,*) line
write(2,*) line
end do
do i=28,38
read(1,*)
end do
do i=39,45
read(1,*) line
write(2,*) line
end do
*应该注意的是,我在编译时假设缓冲 i/o,尽管这似乎只是最低限度地加快了速度。
我很好奇这是否是完成我的任务的最有效方式。如果上述方法实际上是使用 fortran90 执行此操作的最佳方法,是否还有其他语言更适合此任务?
*更新:确保我使用的是缓冲 i/o,手动查找最有效的块大小/块计数。这将速度提高了约 7%。请注意,我正在使用的文件没有固定的记录长度。
【问题讨论】:
-
读取大文本文件的最快简便方法?把它放在一个非常快的磁盘系统上,不要写慢代码来读它,以免伤到自己的脚。还有更复杂的解决方案,但它们非常依赖于操作系统,并且实际的 IO 模式非常依赖于硬件,因为 最快 方式通常会完全绕过页面缓存。对于它的价值,
mmap()通常是一个非常糟糕的选择,当您只想从头到尾流式传输文件而不重新读取文件的任何部分时。mmap()在您必须从整个文件的随机位置进行多次重新读取时效果最佳。 -
也许使用
STREAM访问会比按顺序跳过特定行更快。 -
谢谢,我会看看使用流 i/o 是如何工作的。
-
通过流访问,您需要解析文件以查找行尾标记,我看不出这有什么帮助..(除非所有行的长度完全相同。)跨度>
-
是的,我得出了同样的结论,即流访问无济于事。不幸的是,这些条目的长度不相等,因此减少了一些简单的解决方案。最终坚持使用类似于我上面原来的方案。在 C++ 中有一个解决方案:stackoverflow.com/questions/26736742/…,看起来很有希望,但我宁愿给我的代码额外的时间,也不愿为这项任务学习 C++。
标签: file text fortran fortran90