我在使用 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 在评论中提到的,它只是使用 sysopen和 sysread ,这两者最终都会触底到普通的操作系统调用。坦率地说,一旦您接触磁盘 I/O,您就迷失了方向:您唯一的希望就是尽可能少地接触它。
鉴于您的文件是 500MB,无论如何您都必须读取磁盘文件的所有字节,并且您必须面向行的传递来处理每一行,我不太明白为什么需要分两次执行此操作。为什么要将其从根本上的一次通过算法转变为二次通过算法?
如果您不显示任何其他代码,我们无法真正判断您所做的是快还是慢。没有测量,我们就不能说出任何实质性的东西。您是否尝试使用 bufio.Scanner() 编写直接代码?首先,然后 measure performance ?
关于perl - 使用 Go 将文本文件从硬盘读取到内存的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26811546/