CreateProcess的快速替代品

时间:2012-09-27 13:23:08

标签: performance delphi exe pascal createprocess

我正在寻找Delphi中CreateProcess的快速替代方法来在exe中执行某些计算,包括XML中的几个返回值。 目前,我正在使用某些参数调用C#-exe。其中一个电话约需要。 0.5s - 这是方式昂贵,因为这个exe需要被调用几百次(不幸的迭代调用,即多线程不会加速工作)。

我当前的代码看起来像这样(找到解决方案来获取StackOverflow上的exe somwhere的控制台输出)。

IsExecutable := CreateProcess(
            nil,
            PChar(WorkDir + Exe + CommandLine),
            nil,
            nil,
            True,
            HIGH_PRIORITY_CLASS,
            nil,
            nil,
            StartupInfo,
            ProcessInformation);
CloseHandle(StdOutPipeWrite);
    if IsExecutable then
      try
        repeat
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
          if BytesRead > 0 then
          begin
            Buffer[BytesRead] := #0;
            Result := Result + Buffer;
          end;
        until not WasOK or (BytesRead = 0);
        WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
      finally
        CloseHandle(ProcessInformation.hThread);
        CloseHandle(ProcessInformation.hProcess);
      end
不过,我对Delphi不是很好 - 实际上,我觉得“我不知道我在做什么”的狗咪模因......

5 个答案:

答案 0 :(得分:8)

创建新流程非常昂贵。没有其他方法可以使用CreateProcess。这里没有快速修复。没有神奇的按钮可以让流程创建速度超快。

解决问题的方法是停止创建一个新流程。在您的流程中执行此任务。

答案 1 :(得分:3)

您是否每次都需要创建新流程?或者你可以重复使用相同的实例吗? 您可以使用一些低级控制台输入/输出管道(您的代码看起来就像现在尝试这样做:)),或者您可以使用某种IPC(互斥+共享内存,在两个进程之间复制数据) ),或者您可以通过TCP / IP进行通信来使用更多的n层(或客户端/服务器)方法(RemObjects SDK非常适合这个,有.Net和Delphi库,通过TCP / IP进行通信,或者Windows消息,命名管道等)。然而,最后一种方法由于抽象而增加了一些延迟/开销,但是比在.Net和Delphi中实现双方更容易使用(这不是那么困难)。

答案 2 :(得分:3)

David wroteAndré wrote一样,您无法更改此内容。

这是真正的big differences between Windows and Linux之一。 Windows中的CreateProcess非常昂贵,而Linux中的fork便宜。另一方面,Linux fork之后通常是exec,价格昂贵。这就是.NET introduced the AppDomain which is faster

的原因

您可以通过几个方向将.NET代码集成到您的流程中,例如Arnaud wrote

您可以做的另一件事是在Delphi进程和.NET进程之间进行IPC(例如使用命名管道),并让.NET进程为每个请求使用AppDomains。

答案 3 :(得分:1)

这里很慢的是创建一个新进程,并且每次运行可执行文件时都会启动整个.Net框架进程。

为了获得最佳性能,最好将C#进程公开为COM,然后直接从Delphi中调用它。

在这种情况下,通过TCP / IP进行远程连接是不值得的,我想。几年前,我在本地机器上使用RemObjects的速度实验很糟糕。

您需要的是致电COM互操作,您可能对以下内容感兴趣:

Delphi非常好地处理COM对象,您可以从Delphi代码中轻松调用C#方法。

答案 4 :(得分:0)

使用线程池或IOCP代替?是的,它有点复杂和资源消耗,但不需要执行外部进程。新的ThreadPool API(Vista和更高版本)为您提供了更多的机会和灵活性(您甚至可以标记长时间运行的任务):