Reputation: 11101
I have performance problems executing an .exe using Process.Start()
. The execution takes roughly 5 times longer from .NET then it does from console. What can cause this? Here is a test program:
public static void Main(string[] argv)
{
for (int i = 0; i < 10; i++)
{
ProcessStartInfo psi = new ProcessStartInfo(ExePath, Args);
Process ps = new Process {StartInfo = psi};
Stopwatch sw = Stopwatch.StartNew();
ps.Start();
ps.WaitForExit();
sw.Stop();
Console.WriteLine(i+" Elapsed time: " + sw.ElapsedMilliseconds + "ms.");
Thread.Sleep(1000);
}
}
The result is this:
0 Elapsed time 4310ms.
1 Elapsed time 4330ms.
2 Elapsed time 4280ms.
...
Running it in a cmd window returns almost immediately (sub 1 second execution). Tried timing it in the console using
> powershell Measure-Command { cmd /c start /wait %EXE% %ARGS% }
Which shows around 750ms for the execution, which is a good 5-6 times faster. Not sure I did that right, but 750ms feels like a likely execution time.
At first I was reading std out and thought it was related to this, see e.g. Process takes longer to finish than in CMD and similar questions. Obviously in the simple test program I'm not reading any output now, just executing.
Possible causes I have alreay ruled out that cause no difference in exec time:
What I do know about the executable (It's the rust statement completion tool 'racer' https://github.com/phildawes/racer) is that it will go off and open lots of files. Could that matter when coming from the .NET host, e.g. wrt. security, that causes the slowdown? What else could cause the huge performance difference?
Upvotes: 12
Views: 8841
Reputation:
A very late comment, but today 2023, it seems to be still the case. Running on a nvidia jetson, with 4GB memory the difference is huge, when ran from C# it is 3 times slower....
I already ran some platform functions in python, which tell me how much memory and such I have. Here a code snippet.
I don 't have time for now to solve the issue getting the code right performing is a huge challenge, as most examples, even codegpt sucks at generating the best code for a ssim which has decent performance and accurateness.
Maybe somebody sees this remark and has the golden bullet to solve the question.
ProcessStartInfo processStartInfo = new(_pathHelper.PythonPath.Value, arguments)
{
WorkingDirectory = workingDirectory,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
using var proc = Process.Start(processStartInfo)!;
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.OutputDataReceived += (_, e) => streamStdOutWriter.WriteIfNotNull(e.Data);
proc.ErrorDataReceived += (_, e) => errors.AddIfNotNull(e.Data);
try
{
_logger.LogInformation($"{_pathHelper.PythonPath.Value} {arguments}");
await proc.WaitForExitAsync(two.Token);
Upvotes: 0
Reputation: 3050
The difference in running time in this case was due to different versions of the executed (racer.exe
) file, and had nothing to do with the fact that one was being executed from a .NET process and the other from the command line.
There shouldn't be a difference when running an executable from .NET as it is simply using system calls to execute the program.
Upvotes: 5
Reputation: 941407
ps.WaitForExit();
That's the statement that makes the difference. Your cmd.exe command doesn't wait for the process to terminate. Either remove WaitForExit() or use "cmd /c start /wait %EXE% %ARGS%" to compare apples to oranges.
Or in other words, you didn't measure how long it took to start a process, you measured how long the process was running.
Upvotes: 2