Lachee / discord-rpc-csharp

C# custom implementation for Discord Rich Presence. Not deprecated and still available!
MIT License
561 stars 93 forks source link

Reduce overhead in `ManagedNamedPipeClient` during connection loop #237

Closed peppy closed 11 months ago

peppy commented 11 months ago

The implementation of NamedPipeClientStream has some egregious use of SpinOnce:

https://github.com/dotnet/runtime/blob/d59af2cf097acb100ad6a9cba652be34be6f4a2e/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs#L151-L155

This adds perceivable overhead to the connect process, which we really don't want on a background thread. It is especially noticeable when discord is not running and the reconnect process is constantly running in the background.

To get around this, we can request a connect timeout of 0 ms from the underlying API. Checking the implementations, this seems like a valid method, as long as there is external retry logic in place (which there is in the local class).

Over 5 failed connection attempts:

Before After
Parallels Desktop 2021-09 at 09 36 44 Parallels Desktop 2023-07-12 at 09 34 33

Note that this profiled view is considering thread running time, not all time. It does not include actual Thread.Sleep sleep time, and the overhead seen here is actual CPU time being used from spinlocking.

Tested on Windows, macOS and linux.

peppy commented 11 months ago

Thanks @Lachee. Would appreciate if there is a nuget release for this in the near future so we don't have to locally hack around it in an ugly way!

Lachee commented 11 months ago

Thanks @Lachee. Would appreciate if there is a nuget release for this in the near future so we don't have to locally hack around it in an ugly way!

Yeah, just pushed that now and it is validating on Nuget as we speak. It will be version 1.1.4.20