perf: reduce diagnostics and queued dispatch allocations in 2.3.2
This commit is contained in:
8 files changed
+152
-36
No files matched your search
+35
-7
@@ -57,6 +57,8 @@ namespace ShrinkEventBus
|
||||
private static readonly IShrinkEventBus DefaultBus = CreateDefaultBus();
|
||||
private static Action<IShrinkEvent, Type, ShrinkBusKey>? _posted;
|
||||
private static Action<ShrinkEventTrace>? _detailedPosted;
|
||||
private static readonly object DetailedObserverGate = new();
|
||||
private static Action<ShrinkEventTrace>[]? _detailedObserverSnapshot;
|
||||
|
||||
internal static event Action<IShrinkEvent, Type, ShrinkBusKey> Posted
|
||||
{
|
||||
@@ -78,14 +80,41 @@ namespace ShrinkEventBus
|
||||
|
||||
internal static event Action<ShrinkEventTrace> DetailedPosted
|
||||
{
|
||||
add => _detailedPosted += value;
|
||||
remove => _detailedPosted -= value;
|
||||
add
|
||||
{
|
||||
lock (DetailedObserverGate)
|
||||
{
|
||||
_detailedPosted += value;
|
||||
PublishDetailedObserverSnapshot();
|
||||
}
|
||||
}
|
||||
remove
|
||||
{
|
||||
lock (DetailedObserverGate)
|
||||
{
|
||||
_detailedPosted -= value;
|
||||
PublishDetailedObserverSnapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PublishDetailedObserverSnapshot()
|
||||
{
|
||||
var invocationList = _detailedPosted?.GetInvocationList();
|
||||
Action<ShrinkEventTrace>[]? snapshot = null;
|
||||
if (invocationList != null)
|
||||
{
|
||||
snapshot = new Action<ShrinkEventTrace>[invocationList.Length];
|
||||
for (var i = 0; i < snapshot.Length; i++)
|
||||
snapshot[i] = (Action<ShrinkEventTrace>)invocationList[i];
|
||||
}
|
||||
Volatile.Write(ref _detailedObserverSnapshot, snapshot);
|
||||
}
|
||||
|
||||
internal static bool HasDetailedPostedObservers
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => Volatile.Read(ref _detailedPosted) != null;
|
||||
get => Volatile.Read(ref _detailedObserverSnapshot) != null;
|
||||
}
|
||||
|
||||
public static IShrinkEventBus Default => DefaultBus;
|
||||
@@ -212,15 +241,14 @@ namespace ShrinkEventBus
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void NotifyDetailedPosted(ShrinkEventTrace trace)
|
||||
{
|
||||
var observers = Volatile.Read(ref _detailedPosted);
|
||||
var observers = Volatile.Read(ref _detailedObserverSnapshot);
|
||||
if (observers == null)
|
||||
return;
|
||||
var invocationList = observers.GetInvocationList();
|
||||
for (var i = 0; i < invocationList.Length; i++)
|
||||
for (var i = 0; i < observers.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Action<ShrinkEventTrace>)invocationList[i])(trace);
|
||||
observers[i](trace);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
||||
@@ -59,15 +59,29 @@ namespace ShrinkEventBus
|
||||
internal sealed class ShrinkSchedulerWorkItem
|
||||
{
|
||||
private readonly UniTaskCompletionSource? _completion;
|
||||
private readonly Delegate _action;
|
||||
|
||||
public ShrinkSchedulerWorkItem(Action action)
|
||||
{
|
||||
_action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
}
|
||||
|
||||
public ShrinkSchedulerWorkItem(Func<UniTask> action, bool awaitable)
|
||||
{
|
||||
Action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
_action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
if (awaitable)
|
||||
_completion = new UniTaskCompletionSource();
|
||||
}
|
||||
|
||||
public Func<UniTask> Action { get; }
|
||||
public UniTask Invoke()
|
||||
{
|
||||
if (_action is Action synchronousAction)
|
||||
{
|
||||
synchronousAction();
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
return ((Func<UniTask>)_action)();
|
||||
}
|
||||
public UniTask Completion => _completion?.Task ?? UniTask.CompletedTask;
|
||||
|
||||
public void Complete() => _completion?.TrySetResult();
|
||||
@@ -169,7 +183,7 @@ namespace ShrinkEventBus
|
||||
{
|
||||
try
|
||||
{
|
||||
await item.Action();
|
||||
await item.Invoke();
|
||||
item.Complete();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
@@ -187,7 +201,7 @@ namespace ShrinkEventBus
|
||||
{
|
||||
try
|
||||
{
|
||||
item.Action().GetAwaiter().GetResult();
|
||||
item.Invoke().GetAwaiter().GetResult();
|
||||
item.Complete();
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
@@ -232,6 +246,7 @@ namespace ShrinkEventBus
|
||||
private readonly MainThreadDispatcherContract _dispatcher;
|
||||
private readonly ShrinkSDK.Runtime.IShrinkDeferredMainThreadDispatcher? _deferredDispatcher;
|
||||
private readonly object _gate = new();
|
||||
private readonly Action _pump;
|
||||
private int _pumpScheduled;
|
||||
private int _disposed;
|
||||
private bool _discardPending;
|
||||
@@ -241,6 +256,7 @@ namespace ShrinkEventBus
|
||||
_queue = new ShrinkSchedulerQueue(name, options);
|
||||
_dispatcher = ShrinkEventBusRuntime.MainThreadDispatcher;
|
||||
_deferredDispatcher = _dispatcher as ShrinkSDK.Runtime.IShrinkDeferredMainThreadDispatcher;
|
||||
_pump = () => PumpAsync().Forget();
|
||||
}
|
||||
|
||||
public bool IsOnSchedulerThread => _dispatcher.IsMainThread;
|
||||
@@ -269,11 +285,7 @@ namespace ShrinkEventBus
|
||||
lock (_gate)
|
||||
{
|
||||
if (_disposed != 0) return ShrinkDeferredPostStatus.Stopped;
|
||||
var item = new ShrinkSchedulerWorkItem(() =>
|
||||
{
|
||||
action();
|
||||
return UniTask.CompletedTask;
|
||||
}, awaitable: false);
|
||||
var item = new ShrinkSchedulerWorkItem(action);
|
||||
if (!_queue.TryEnqueue(item)) return ShrinkDeferredPostStatus.QueueFull;
|
||||
return SchedulePump() ? ShrinkDeferredPostStatus.Accepted : ShrinkDeferredPostStatus.SchedulerRejected;
|
||||
}
|
||||
@@ -333,8 +345,8 @@ namespace ShrinkEventBus
|
||||
try
|
||||
{
|
||||
accepted = _deferredDispatcher != null
|
||||
? _deferredDispatcher.TryPostDeferred(() => PumpAsync().Forget())
|
||||
: _dispatcher.TryPost(() => PumpAsync().Forget());
|
||||
? _deferredDispatcher.TryPostDeferred(_pump)
|
||||
: _dispatcher.TryPost(_pump);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -398,11 +410,7 @@ namespace ShrinkEventBus
|
||||
{
|
||||
if (Volatile.Read(ref _disposed) != 0)
|
||||
return false;
|
||||
var item = new ShrinkSchedulerWorkItem(() =>
|
||||
{
|
||||
action();
|
||||
return UniTask.CompletedTask;
|
||||
}, awaitable: false);
|
||||
var item = new ShrinkSchedulerWorkItem(action);
|
||||
if (!_queue.TryEnqueue(item))
|
||||
return false;
|
||||
ScheduleWorkers();
|
||||
@@ -503,11 +511,7 @@ namespace ShrinkEventBus
|
||||
return true;
|
||||
}
|
||||
|
||||
var item = new ShrinkSchedulerWorkItem(() =>
|
||||
{
|
||||
action();
|
||||
return UniTask.CompletedTask;
|
||||
}, awaitable: false);
|
||||
var item = new ShrinkSchedulerWorkItem(action);
|
||||
if (!_queue.TryEnqueue(item))
|
||||
return false;
|
||||
_signal.Set();
|
||||
|
||||
Reference in new issue
Block a user