perl - 使用 Go 将文本文件从硬盘读取到内存的最快方法是什么?

标签 perl file go

我在使用 Perl 多年后才开始使用 Go,从最初的测试来看,从硬盘驱动器读取文本文件到散列中的速度似乎不如 Perl。

在 Perl 中,我使用“File::Slurp”模块,它有助于非常快地将文件读入内存(读入字符串变量、数组或散列)——在硬盘读取吞吐量的限制下。

我不确定使用 Go 阅读的最佳方式是什么,例如500MB CSV 文件,其中 10 列存入内存(进入哈希),其中哈希的键是第一列,值是其余 9 列。

实现此目标的最快方法是什么?目标是读取并存储到一些 Go 内存变量中,速度与硬盘驱动器传输数据的速度一样快。

这是输入文件中的一行 - 大约有 2000 万行:

1341,2014-11-01 00:01:23.588,12000,AV7WN259SEH1,1133922,SingleOven/HCP/-PRODUCTION/-23C_30S,0xd8d2a106d44bea07,8665456.006,5456-02,3010-39AVNHO2,5456-02,3010-30SE

平台是 Win 7 - i7 英特尔处理器和 16GB 内存。如果这样做有好处,我也可以在 Linux 上安装 Go。

编辑:

所以一个用例是——将整个文件加载到内存中,尽可能快地加载到 1 个变量中。稍后我可以扫描该变量,拆分(全部在内存中)等。

另一种方法是在加载期间将每一行存储为键值对(例如,在 X 字节通过后或\N 字符到达后)。

对我来说——这两种方法可以产生不同的性能结果。但由于我是 Golang 的新手 - 我可能需要几天的时间才能在 Golang 中尝试不同的技术来制作最佳性能算法。

我想学习在 Golang 中执行上述操作的所有可能方法以及推荐的方法。此时我不关心内存使用情况,因为这个过程将在第一个文件处理完成后立即重复 10,000 次(每个文件将在处理完成后立即从内存中删除)。文件范围从 50MB 到 500MB。由于有数千个文件 - 任何性能提升(甚至每个文件 1 秒的提升)都是显着的整体提升。

我不想让以后如何处理数据的问题变得复杂,只是想了解从驱动器读取文件并存储在哈希中的最快方法。我将对我的发现进行更详细的基准测试,并且随着我更多地了解在 Golang 中执行此操作的不同方法以及听到更多建议。我希望有人已经对这个主题进行了研究。

最佳答案

ioutil.ReadFile将整个文件读入内存可能是一个很好的开始。话虽如此,这听起来像是对内存资源的不当使用。问题断言 File::Slurp 很快,but this is not general consensus针对您正在执行的特定任务,即逐行处理。

声称 Perl 以某种方式“快速”地做事。我们可以看看source code到 Perl 的 File::Slurp。据我所知,它没有施展任何魔法。正如 Slade 在评论中提到的,它只是使用 sysopensysread ,这两者最终都会触底到普通的操作系统调用。坦率地说,一旦您接触磁盘 I/O,您就迷失了方向:您唯一的希望就是尽可能少地接触它。

鉴于您的文件是 500MB,无论如何您都必须读取磁盘文件的所有字节,并且您必须面向行的传递来处理每一行,我不太明白为什么需要分两次执行此操作。为什么要将其从根本上的一次通过算法转变为二次通过算法?

如果您不显示任何其他代码,我们无法真正判断您所做的是快还是慢。没有测量,我们就不能说出任何实质性的东西。您是否尝试使用 bufio.Scanner() 编写直接代码?首先,然后 measure performance

关于perl - 使用 Go 将文本文件从硬盘读取到内存的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26811546/

相关文章:

rest - 在 Go 语言中调用 REST 路由方法中的对象方法

json - 如何在 Go 中打印出 JSON

C - 根据格式读入文件

asp.net - 如何验证文件上传的文件类型?

c - 从文件中读取文本,将行存储在数组中

string - 如何检查环境变量是否已设置?

go - 是否可以定义一个返回接口(interface)的无名函数?

Perl split() 函数不处理保存为变量的管道字符

perl - 如何确定一个对象是否在 Perl 中实现了一个方法?

perl - 'ne' 在 do-while 循环中不起作用,而 '!=' 起作用