perf: reduce diagnostics and queued dispatch allocations in 2.3.2
Publish UPM package / publish (push) Successful in 2s
Publish NuGet packages / publish (push) Canceled after 3m12s

This commit is contained in:
cneicy committed 2026-11-06 20:52:09 +08:00
1 parent 901ad18453
commit 0449e82c0c
8 files changed
+152 -36

No files matched your search

+35 -7
View File
@@ -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)
{
+25 -21
View File
@@ -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();