Search code examples
performancedelphiexecreateprocess

Fast alternative to CreateProcess


I’m looking for a fast alternative to CreateProcess in Delphi to execute certain calculations in an exe, including several return values in XML. Currently, I’m calling an C#-exe with certain parameters. One of these calls takes approx. 0.5s, which is way to expensive, since this exe needs to be called a couple of hundred times (unfortunately iterative calls, i. e. multithreading won’t speed up the job).

My current code looks like this (found the solution to get the console output of the exe somewhere on StackOverflow).

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

By the way, I’m not very good at Delphi. Actually, I kinda feel like the “I have no idea what I’m doing” dog-meme-thing …


Solution

  • Do you need to create a new process every time? Or can you re-use the same instance? You can do it with some low level console input/output piping (your code looks like you're trying to do this now :) ), or you can use some kind of IPC (mutex+shared memory, to copy data between 2 processes), or you can use a more n-tier (or client/server) approach by communicating via TCP/IP (RemObjects SDK is very good for this one, has both .Net and Delphi libs, which communicate via TCP/IP, or windows messages, named pipes, etc). However the last approach adds some more delay/overhead because of the abstraction but is much easier to use than to implement both sides in .Net and Delphi yourself (it is not that difficult btw).