【问题标题】:Divide work, assign task to an array of threads划分工作,将任务分配给线程数组
【发布时间】:2012-07-05 20:25:21
【问题描述】:

我需要对备忘录中的文本进行数学计算。 [文件大小:~2mb]

一个合适的例子是我需要解码的编码文本。

我将备忘录文本传递给一个字符串以便对其进行解码。 我想使用线程运行我的解码功能会更快。 但是经过一番谷歌搜索后,我没有找到适合我目的的好例子。

示例函数:

function entr_base_N(my_text:String):String;
var
    ts_hamil64:Integer;
begin
    For ts_hamil64 := 1 to Length(my_text) do
    begin
         Result:= Result + Chr(Ord(my_text[ts_hamil64])+10)
    end;    
end;
.....
.....
Memo1.Text:=entr_base_N(Memo1.Text)

我想将工作分成小块,平均分配工作,假设 3..8 个线程并将我的解码功能分配给这些线程。你能指导我吗?

处理文本文件的当前时间:~35 秒。 感谢您的热心帮助。

【问题讨论】:

  • @Kabamaru,因为有效的多线程非常依赖于操作的数据。
  • 如果你只有2000行,启动线程的开销可能比手头的任务要大。另外,为什么要 100 个线程?你有 100 个处理器吗?
  • @Kabamaru:如果你的 CPU 有 8 个逻辑处理器,你不会受益于超过 8 个线程。
  • 文件有多大。多少个字符?
  • @Kabamaru 我相信我现在有了答案。瓶颈不在Q中的代码!

标签: multithreading delphi delphi-xe2


【解决方案1】:

线程不是问题。您的函数entr_base_N 立即运行。在调试器中尝试。你会发现它根本不需要时间。在现代计算机上处​​理 2MB 的字符串是微不足道的。也就是说,我总是建议在可能的情况下预先分配一个返回缓冲区。

所有时间都花在将结果字符串发送回备忘录控件上。发生的事情是您将#13 和#10 字符转换为#23 和#20。无论出于何种原因,备忘录控件都不喜欢这样。在我看来,您发送回一个根本没有换行符的字符串,并且备忘录的自动换行代码表现不佳。

一种快速而肮脏的方法是在你的备忘录上将WordWrap 设置为False

这里的重要教训是,您必须在尝试优化之前正确识别瓶颈。不过,这很容易落入陷阱,正如我最初为回答这个问题所做的努力所表明的那样。

【讨论】:

  • 我只是在观察这种行为!你说的对!!它的运行速度正好快 20 倍。奇怪...非常感谢。 [entr_base_N : 这里的代码只是一个例子。现在大约需要 1.5 秒]
  • 感谢大家的帮助。我也会尝试使用多线程。
  • 多线程无济于事。现在 1.5s 仍在向备忘录发送文本。修改字符串的代码实际上是即时的。这是极少量的数据。在尝试提高性能之前,您必须始终找出瓶颈。
  • +1,我认为这是问题所在,但不知道如何解释,所以我只是停了下来。在这里,线程无济于事。
  • +1 这是一个很容易掉入的陷阱,正如我最初尝试回答这个问题时所做的努力所证明的那样。
【解决方案2】:

要更快地分配到 Memo1.Text,您可以使用以下方法:

memo1.Perform(wm_setredraw, 0, 0);
try
  memo1.Text:= entr_base_N(memo1.Text);
finally
  memo1.Perform(wm_setredraw, 1, 0);
  memo1.invalidate;
end;

【讨论】:

    猜你喜欢
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多