【发布时间】:2014-11-07 23:05:30
【问题描述】:
在使用 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-359-NW17 p>
平台是 Win 7 - i7 Intel 处理器和 16GB 内存。如果这样做有好处,我也可以在 Linux 上安装 Go。
编辑:
所以一个用例是 - 尽可能快地将整个文件加载到内存中到 1 个变量中。稍后我可以扫描该变量,拆分(全部在内存中)等。
另一种方法是在加载期间将每一行存储为键值对(例如,在 X 位被传递或 \N 字符到达之后)。
对我来说 - 这两种方法可以产生不同的性能结果。但由于我对 Golang 很陌生 - 我可能需要几天时间才能在 Golang 中尝试不同的技术来制作最佳性能算法。
我想学习在 Golang 中完成上述所有可能的方法以及推荐的方法。在这一点上,我不关心内存使用情况,因为这个过程将在第一个文件处理完成后重复 10,000 次(处理完成后每个文件都会从内存中删除)。文件范围从 50MB 到 500MB。由于有数千个文件 - 任何性能提升(甚至每个文件 1 秒的提升)都是显着的整体提升。
我不想增加关于稍后将如何处理数据的问题的复杂性,而只想了解从驱动器读取文件并存储在哈希中的最快方法。我将对我的发现进行更详细的基准测试,并且当我更多地了解在 Golang 中执行此操作的不同方法以及听到更多建议时。我希望有人已经对这个主题进行过研究。
【问题讨论】:
-
至少显示几行文件?
-
File::Slurp 是根据系统的 open(2)/read(2) 实现的。我想 Golang 的 I/O 包提供了一种读取整个文件的方法,只需最少的系统调用,并且以类似的方式没有缓冲。
-
你为什么平台开发这个? Go 提供对
syscall.Mmap函数的访问,这是一种符合 POSIX 标准的将文件映射到内存的方法。这可能是将文件读入[]byte的最快方法。虽然这不能回答您的问题,但它是您进一步了解的一个很好的起点。 -
没什么可继续的。您可以只对程序的一部分进行基准测试,尝试观察 CPU 的运行情况,尝试几种 I/O 代码方法。 (而且,说起来很奇怪,但它只有 500MB;即使是一种相对低效的阅读方式也不应该花费 太 的时间来阅读许多应用程序。)
-
SirDarius - 您能否发布一个使用 syscall.Mmap 读取 input.csv 文件的 Go 代码?