我正在用delphi阅读非常广泛的文件
该文件是逗号分隔的,大部分时间用于解析字符串。
逻辑如下
我想并行运行步骤3,目前正在查看OmniThreadLibrary。
什么是最好的方法?
我要用平行的吗?管道?还是排队?
我正在考虑使用“并行For”,但问题是我不知道该文件有多少行
发布于 2014-03-17 13:37:38
使用多个线程读取文件没有什么好处。这部分过程是I/O绑定,而不是CPU绑定。因此,最好从单个线程读取整个文件。
然后,您需要将文件拆分成行。这是一件很难并行的事情,因为这是一个依赖的问题。行N+1从N行结束的位置开始。这将是最简单的分裂成行在一个单一的线程。
但是您可以在I/O和拆分成行之间运行一条管道。以大块的方式读取文件(比方说一次读取几十个KBs )。并将每个块向下传递到要处理成行的管道中。您可能需要在任何时候为允许在管道中放置多少数据设置一个上限。否则,如果文件读取速度比处理速度快,您可能会耗尽内存。
因此,对于这个管道,您有一个读取文件的生产者和一个将文件的内容拆分成行的使用者。
然后你可以运行另一条管道。在生产者结束时,您有由上一步产生的行列表。这会将管道向下推到处理每一行的使用者。消费者将以并行的方式来实现这一点。
发布于 2014-03-17 15:02:24
将解析分割成块,例如,10.000行可能是一种选择。我不知道OmniThread库,所以您必须自己完成的部分,但是代码的基本结构如下所示:
CONST ChunkSize = 10000;
VAR ARR : ARRAY[1..ChunkSize] OF STRING;
VAR Lines : Cardinal;
VAR TXT : TextFile;
VAR FileName : STRING;
Lines:=0;
AssignFile(TXT,FileName); RESET(TXT);
WHILE NOT EOF(TXT) DO BEGIN
IF Lines=ChunkSize THEN BEGIN
<Do Parallel For on ARR>;
Lines:=0
END;
INC(Lines);
READLN(ARR[Lines])
END;
<Do Parallel For on ARR - only "Lines" lines>注意,代码假定该部分只在处理完数组中的所有条目后才会继续。
发布于 2014-03-17 15:46:01
您不需要知道使用并行的行总数,因为您可以使用阻塞集合来迭代。只是不要错过在添加了最后一行后调用CompleteAdding。
请注意,与线程和队列管理相比,当每个单个任务只需少量时间时,并行-For的性能可能会严重下降。
您还可以考虑使用BackgroundWorker抽象,并在每个WorkItems中调度多行。
https://stackoverflow.com/questions/22454967
复制相似问题