PythonEngine.Shutdown() / Runtime.Shutdown() slowness
See original GitHub issueEnvironment
- Pythonnet version: 3.0.1
- Python version: 3.9.12
- Operating System: Windows or Linux
- .NET Runtime: net6.0
Details
- Describe what you were trying to get done.
We are embedding Python in a .NET app using pythonnet.
The call to PythonEngine.Shutdown()
at the exit of this app lasts for more than 2 minutes.
Looking at the shutdown with a profiler shows that most of the time is spent in Runtime.TryCollectingGarbage()
.
Looks like the more memory is allocated on the C# side the more the shutdown (i.e. calls to GC.Collect()
) is slow.
- Minimal, Complete, and Verifiable example
using Python.Runtime;
namespace Test;
static class Program
{
static void Main()
{
var mem = new List<Array>();
Runtime.PythonDLL = @$"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\AppData\Local\Programs\Python\Python39\python39.dll";
PythonEngine.Initialize();
var threadState = PythonEngine.BeginAllowThreads();
using (Py.GIL())
{
using (var scope = Py.CreateScope())
{
scope.Set("a", 1);
scope.Set("b", 2);
scope.Exec("result = a + b");
var result = scope.Get("result").As<int>();
Console.WriteLine($"Sum = {result}");
}
}
// allocate dotnet-managed memory unrelated to pythonnet
var rnd = new Random();
for (var i = 0; i < 100_000_000; ++i)
{
mem.Add(new byte[rnd.Next(1, 10)]);
}
PythonEngine.EndAllowThreads(threadState);
Console.WriteLine("Shutdown start");
var start = DateTime.Now;
PythonEngine.Shutdown();
var diff = DateTime.Now - start;
Console.WriteLine($"Shutdown stop {diff.TotalSeconds}");
}
}
Typical output:
Sum = 3
Shutdown start
Shutdown stop 61.6796983
Issue Analytics
- State:
- Created 10 months ago
- Reactions:4
- Comments:13 (8 by maintainers)
Top Results From Across the Web
Random Access Violations on shutdown · Issue #1977
NET Runtime: . ... I am getting random access violations during shutdown in p... ... Forms import Form def example(): form = Form()...
Read more >Error Calling Python code from .Net Core 6 web api
Runtime I added this line before PythonEngine. ... ShutDown() to execute without throwing the BinaryFormatter serialization exception.
Read more >pythonnet
NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application ......
Read more >Why is CMD very very slow? To execute any command or ...
cmd is not slow. It's just a command interpreter after all. Some things can be blamed for the slowness: Your own program; Process...
Read more >Why is Python slower than R?
In general though it doesn't really matter much. Neither language is chosen for its speed. They are both slow when running straight commands...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@AlexGilmor If you want to shut down Python, use
Shutdown
. The slowness is due to to multiple garbage collection rounds and (potentially contributing, but not the only factor) the runtime stashing that was introduced to allow forAppDomain
switching.@nlogozzo Since you are not actually using the stashing, you can try setting a no-op formatter:
Your issue does not occur when the project is ran in .NET 7 using a Release configuration. When ran in Debug configuration, the shutdown does indeed slow down significantly - from 0.08 seconds up to 63 seconds.
This does not fix the issue when the code is ran in Debug configuration under .NET 7.