我正在使用delphi阅读非常广泛的文件
该文件以逗号分隔,大部分时间用于解析字符串。
逻辑如下
我希望并行运行第3步,目前正在查看OmniThreadLibrary。
最好的方法是什么?
我要使用Parallel For吗? Pipelene?还是队列?
我正在考虑使用'Parallel For',但问题是我不知道该文件有多少行
答案 0 :(得分:1)
使用多个线程来读取文件没有任何好处。该过程的一部分是I / O绑定而不是CPU绑定。因此,您最好从单个线程中读取整个文件。
然后,您需要将文件拆分为多行。由于存在依赖性问题,因此很难再次并行执行。线N + 1从线N结束的地方开始。在单个线程中分割成行是最简单的。
但是你可以在I / O和分成行之间运行一个管道。以大块读取文件(一次说几十KB)。并将每个块传递到管道中以进行处理。您可能需要在任何时刻设置允许在管道中放置多少数据的上限。否则,如果可以比处理文件更快地读取文件,则可能耗尽内存。
因此,对于这个管道,你有一个读取文件的生产者,以及一个将文件内容分成行的消费者。
然后你可以运行另一个管道。在生产者端,您有上一步生成的行列表。这会将管道推向处理每条生产线的消费者。消费者将以并行方式执行此操作。
答案 1 :(得分:0)
将解析拆分成例如10.000行的块可能是一种选择。我不知道OmniThread库,所以<对ARR并行处理>你必须自己做的部分,但代码的基本结构是这样的:
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>
请注意,该代码假定&lt; Do Parallel For ARR&gt;部分仅在处理完阵列中的所有条目后才继续。
答案 2 :(得分:0)
您不需要知道要使用Parallel-For的总行数,因为您可以使用Blocking Collection进行迭代。添加最后一行时,不要错过调用CompleteAdding。
请注意,与线程和队列管理相比,当每个单个任务只需要少量时间时,Parallel-For的性能可能会大幅降低。
您也可以考虑使用BackgroundWorker抽象并在每个WorkItems中安排多行。