将程序转换为多线程,利用多核cpu

ava*_*var 1 delphi multithreading

我有一个简单的程序,只有一个程序.

Procedure TForm1.btnKeywrdTransClick(Sender: TObject);
Var
  i, ii             : integer;
  ch_word, zword, uy_word: widestring;
Begin
  TntListBox1.items.LoadFromFile('d:\new folder\chh.txt'); //Chinese 
  TntListBox2.items.LoadFromFile('d:\new folder\uyy.txt'); //Uyword
  TntListBox4.items.LoadFromFile(Edit3.text); //list of poi files
  For I := 0 To TntListBox4.items.Count - 1 do
  Begin
  TntListBox3.items.LoadFromFile(TntListBox4.Items[i]);
  zword := tntlistbox3.Items.Text;      //Poi
  For ii := 0 To TntListBox1.Items.count - 1 Do
  Begin
    loopz;
    ch_word := tntlistbox1.Items[ii];
    uy_word := ' ' + TntListBox2.items[ii] + ' ';
    zword := wideFastReplace(zword, ch_word, uy_word, [rfReplaceAll]); //fastest, and better for large text
  End;
  TntListBox3.Items.text := zword;
  TntListBox3.items.SaveToFile(TntListBox4.Items[i]);
end;
end;
Run Code Online (Sandbox Code Playgroud)

现在我的新计算机有4个核心,正在使这个程序多线程将使它运行得更快(如果我使用4个线程,每个核心一个线程)?我没有多线程的经验,我需要你的帮助谢谢.

ps:这是Loopz程序

Procedure loopz;
Var
  msg               : tmsg;
Begin
  While PeekMessage(Msg, 0, 0, 0, pm_Remove) Do
  Begin
    If Msg.Message = wm_Quit Then Halt(Msg.WParam);
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  End;
End;
Run Code Online (Sandbox Code Playgroud)

更新1: 从答案,我要做

1 - 使用分析器查找最耗时的代码

2 - 尽可能尝试消除与gui相关的事情

3 - 使用线程.

我会报告回来.谢谢大家.

Cos*_*und 14

首先,使算法尽可能有效,因为它的当前化身:停止使用TListBox存储您的数据!(对不起喊叫)用TStringList替换它们,你将获得巨大的性能提升.这是任何方式都需要的第一步,因为你不能使用来自多个线程的GUI对象(实际上你只能从"主"线程中使用它们).当您将TListBox更改为TStringList时,请为变量指定有意义的名称.我不知道这里有多少人发现你在ListBox4中存储了一个文件名列表,在ListBox3中加载每个文件,使用ListBox1作为"关键字列表",将ListBox2作为"值列表"...真的,这是一个很大的混乱!这里'

Procedure TForm1.btnKeywrdTransClick(Sender: TObject);
Var
  i, ii             : integer;
  ch_word, zword, uy_word: widestring;
  PoiFilesList:TStringList; // This is the list of files that need work
  PoiFile:TStringList; // This is the file I'm working on right now
  KeywordList, ValueList:TStringList; // I'll replace all keywords with corresponding values
Begin

  PoiFilesList := TStringList.Create;
  PoiFile := TStringList.Create;
  KeywordList := TStringList.Create;
  ValueList := TStringList.Create;

  try
    PoiFilesList.LoadFromFile(Edit3.text); //list of poi files
    KeywordList.LoadFromFile('d:\new folder\chh.txt'); //Chinese 
    ValueList.LoadFromFile('d:\new folder\uyy.txt'); //Uyword
    For I := 0 To PoiFilesList.Count - 1 do
    Begin
      PoiFile.LoadFromFile(PoiFilesList[i]);
      zword := PoiFile.Text;      //Poi
      For ii := 0 To KeywordList.count - 1 Do
      Begin
        ch_word := KeywordList[ii];
        uy_word := ' ' + ValueList[ii] + ' ';
        zword := wideFastReplace(zword, ch_word, uy_word, [rfReplaceAll]);
      End;
      PoiFile.text := zword;
      PoiFile.SaveToFile(PoiFilesList[i]);
    end;
  finally
    PoiFilesList.Free;
    PoiFile.Free;
    KeywordList.Free;
    ValueList.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如果你现在看一下代码,它显然是做什么的,而且很明显如何多线程 - 它.你有一个包含文件名的文本文件.您打开这些文件中的每一个,并用相应的值替换所有关键字.您将文件保存回磁盘.这很简单!将KeywordList和ValueList加载到内存中一次,将文件列表拆分为4个较小的列表,启动4个线程,每个线程使用自己的较小文件列表.

我不想写代码的整个多线程变体,因为如果我自己编写它你可能不理解它是如何工作的.如果遇到麻烦,给它一个机会并寻求帮助.

  • 在大多数情况下,所有进行I/O操作的多线程都是不好的建议.原因在于,除非光盘是SSD,否则由于额外的光盘搜索操作,在不同光盘区域上对I/O的并发请求实际上可能比使用单个线程进行I/O慢得多.I/O应该仅限于一个线程,而一个(或多个)其他线程应该进行文本替换.以生产者 - 消费者队列为出发点. (2认同)