首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用delphi OmniThreadLibrary读取平面文件

用delphi OmniThreadLibrary读取平面文件
EN

Stack Overflow用户
提问于 2014-03-17 13:01:04
回答 3查看 371关注 0票数 1

我正在用delphi阅读非常广泛的文件

该文件是逗号分隔的,大部分时间用于解析字符串。

逻辑如下

  1. 打开文件
  2. 读行
  3. 将行拆分成记录数组
  4. 将散列数组传递给下一个过程。
  5. 进入第二步
  6. 关闭文件。

我想并行运行步骤3,目前正在查看OmniThreadLibrary。

什么是最好的方法?

我要用平行的吗?管道?还是排队?

我正在考虑使用“并行For”,但问题是我不知道该文件有多少行

EN

回答 3

Stack Overflow用户

发布于 2014-03-17 13:37:38

使用多个线程读取文件没有什么好处。这部分过程是I/O绑定,而不是CPU绑定。因此,最好从单个线程读取整个文件。

然后,您需要将文件拆分成行。这是一件很难并行的事情,因为这是一个依赖的问题。行N+1从N行结束的位置开始。这将是最简单的分裂成行在一个单一的线程。

但是您可以在I/O和拆分成行之间运行一条管道。以大块的方式读取文件(比方说一次读取几十个KBs )。并将每个块向下传递到要处理成行的管道中。您可能需要在任何时候为允许在管道中放置多少数据设置一个上限。否则,如果文件读取速度比处理速度快,您可能会耗尽内存。

因此,对于这个管道,您有一个读取文件的生产者和一个将文件的内容拆分成行的使用者。

然后你可以运行另一条管道。在生产者结束时,您有由上一步产生的行列表。这会将管道向下推到处理每一行的使用者。消费者将以并行的方式来实现这一点。

票数 2
EN

Stack Overflow用户

发布于 2014-03-17 15:02:24

将解析分割成块,例如,10.000行可能是一种选择。我不知道OmniThread库,所以您必须自己完成的部分,但是代码的基本结构如下所示:

代码语言:javascript
复制
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>

注意,代码假定该部分只在处理完数组中的所有条目后才会继续。

票数 0
EN

Stack Overflow用户

发布于 2014-03-17 15:46:01

您不需要知道使用并行的行总数,因为您可以使用阻塞集合来迭代。只是不要错过在添加了最后一行后调用CompleteAdding。

请注意,与线程和队列管理相比,当每个单个任务只需少量时间时,并行-For的性能可能会严重下降。

您还可以考虑使用BackgroundWorker抽象,并在每个WorkItems中调度多行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22454967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档