Performance 高效的文件I/O和字符串到浮点的转换

Performance 高效的文件I/O和字符串到浮点的转换,performance,multithreading,file-io,large-data-volumes,Performance,Multithreading,File Io,Large Data Volumes,我有一些巨大的(几GB)ASCII文本文件,我需要逐行读取,将某些列转换为浮点,并对这些数字执行一些简单的操作。这是非常简单的东西,除了我认为必须有一种方法来加速整个过程。该程序从未使用100%的CPU核心,因为它在等待I/O上花费了太多的时间。同时,它花费了足够的时间进行计算,而不是I/O,因此它只能完成约8-10 MB/s的原始磁盘I/O。我看到我的硬盘做得比这好得多 在不同的线程中进行I/O和处理可能会有所帮助吗?如果是的话,什么是有效的实施方式?一个重要的问题是如何分配内存来保持每一行,

我有一些巨大的(几GB)ASCII文本文件,我需要逐行读取,将某些列转换为浮点,并对这些数字执行一些简单的操作。这是非常简单的东西,除了我认为必须有一种方法来加速整个过程。该程序从未使用100%的CPU核心,因为它在等待I/O上花费了太多的时间。同时,它花费了足够的时间进行计算,而不是I/O,因此它只能完成约8-10 MB/s的原始磁盘I/O。我看到我的硬盘做得比这好得多

在不同的线程中进行I/O和处理可能会有所帮助吗?如果是的话,什么是有效的实施方式?一个重要的问题是如何分配内存来保持每一行,这样我就不会在这方面遇到瓶颈


编辑:我现在使用的是D编程语言,版本2标准库,主要是更高级的函数。std.stdio.File使用的缓冲区大小为16 KB。

如果您有足够的RAM,可以将整个文件读入一个字符串,在行分隔符上对其进行标记,并根据需要处理标记

在java中,可以使用StringBuilder对象将文件内容读入其中。您还希望使用以下方式启动具有足够内存限制(本例中为2GB)的jvm:

java -Xmx 2048 -Xms 2048 -jar MyMemoryHungryApp.jar
如果不想将整个文件读入字符串,可以迭代地分批读取并处理这些批


事实上,根据文件格式的详细信息,您可能会使用CSVReader(一个开源Java包())通过readAll()方法将您的文件读入内存,最后您将得到一个
列表
,您可以访问它:)。

如果您没有达到100%的CPU,那么您将受到I/O限制,而且,多线程不会有太多/任何改进-您只会有几个线程等待I/O。事实上,如果它们正在访问文件的不同部分,您可能会引入磁盘搜索,从而使情况变得更糟

首先看一些简单的事情:您能增加I/O可用的缓冲RAM的数量吗?(例如,在C++中,文件对象的标准I/O缓冲区很小(例如4KB),设置较大的缓冲区(例如64KB)会对吞吐量产生巨大的差异。 您是否可以在I/O请求中使用较大的缓冲区大小:例如,将64KB的原始数据读入较大的缓冲区,然后自己处理,而不是一次读取一行或一个字节

您正在输出任何数据吗?通过将其缓存在RAM中,而不是将其立即写回磁盘,您可以将IO限制为仅读取输入文件,并帮助加快速度


您可能会发现,一旦加载了大量数据缓冲区,您就开始受到CPU的限制,这时您可以考虑使用多线程—一个线程读取数据,另一个线程处理数据。

首先,我将使用您拥有的程序,并获取它的堆栈快照。这将确切地告诉我们在I/O上花费了多少时间,在CPU上花费了多少时间

然后,如果I/O占主导地位,我会确保读取的缓冲区尽可能大,以最小化磁头运动

然后,如果我看到I/O在CPU上等待,然后CPU在I/O上等待,我会尝试进行异步I/O,这样一个缓冲区可以在另一个缓冲区上运行时加载。(或者,您也可以使用读取器线程,读入备用缓冲区。)

如果I/O不占主导地位,而CPU占主导地位,那么我将看到stackshots告诉我有关CPU活动的信息。如果在浮点数字的格式化中花费了太多的时间,如果数字是相当简单的格式,我会考虑解析它们,因为我可以利用更简单的格式。
这有帮助吗?

通常操作系统会尝试提前读取,如果您没有CPU限制,则应该接近硬盘速度限制

原因可能是:

  • 大文件是碎片化的(您可以对卷进行碎片整理,并检查是否工作得更好)
  • 操作系统不使用预读(作为一种解决方案:在Windows下,您可以使用带有将扫描文件标志的CreateFile)
  • 您没有使用有效的缓冲(例如,如果您一次只从操作系统文件句柄读取几个字节,则速度会很慢。(您可以尝试一次读取较大的块)

当您受到CPU的限制时,您是否应该开始寻找更高效的数据解析方法。

是否考虑过map reduce之类的hadoop?我创建了文件解析器,可以在不到10分钟的时间内解析数百兆字节。不涉及线程。您是否逐行阅读?如何解析一行?如何从字符串转换为浮点?@pixel3cs:现在我几乎所有的东西都在使用标准库。那么你还在使用C吗?(这不是一件坏事:)