-
Notifications
You must be signed in to change notification settings - Fork 0
Diagnostics
The cost of a high update rate is not visible in the code. The
Rambla.Diagnostics package makes it visible. It counts the mutations and the
notifications, it measures the dispatcher, and it gives recommendations.
dotnet add package Rambla.Diagnosticsusing Rambla.Diagnostics;
using DiagnosticsSession session = StateDiagnostics.Attach(viewModel);
// Print the report one time in each second.
Console.WriteLine(session.Snapshot());A session is an observer. It does not change the behavior of the state. The notification order, the coalescing, the coherence and the error behavior stay the same. Dispose the session to detach it.
DiagnosticsSnapshot.ToString() makes this report:
MarketViewModel
Incoming state mutations : 18,420 / sec
UI notifications : 58 / sec
Coalescing : 99.68 %
Dispatcher hops : 60 / sec
Longest UI flush : 2.8 ms
UI thread budget : 17 %
! 'Positions' generated 14,281 notifications/sec. Recommendation: batch related
writes with BeginUpdate(), or for a collection use Batch()/ReplaceSnapshot().
The state alone cannot measure the dispatcher. To get the dispatcher latency, the
number of hops and a correct UI thread budget, put your scheduler in a
DiagnosticsScheduler.
Warning: give the same instance to the state and to Attach. If the two
instances are different, all the dispatcher values are zero.
var scheduler = new DiagnosticsScheduler(DispatcherStateScheduler.ForCurrent());
var vm = new MarketViewModel(scheduler);
using DiagnosticsSession session = StateDiagnostics.Attach(vm, scheduler);Without a DiagnosticsScheduler, the report omits those lines. The other values
stay correct.
| Member | Meaning |
|---|---|
MutationsPerSecond |
The number of value changes in one second. |
NotificationsPerSecond |
The number of notifications in one second. |
FlushesPerSecond |
The number of flushes in one second. |
CoalescingRatio |
The fraction of the mutations that did not become notifications. |
LongestFlush |
The longest flush after the attach operation. |
UiThreadBudget |
The fraction of the time that the UI thread used for the flushes. |
DispatcherHopsPerSecond |
The number of posts that the dispatcher ran in one second. |
AverageDispatcherLatency |
The mean time between the post and the run. |
PeakDispatcherLatency |
The maximum time between the post and the run. |
HotProperties |
The properties with the highest number of notifications. |
Recommendations |
The actions that can decrease the cost. |
HasDispatcherMetrics |
true if a DiagnosticsScheduler gave the dispatcher data. |
var options = new DiagnosticsOptions
{
MaxHotProperties = 10, // default 5
HotNotificationsPerSecond = 500, // default 1000
UiBudgetWarningFraction = 0.3, // default 0.5
};
using var session = StateDiagnostics.Attach(vm, scheduler, options: options);The core package has counters for the full life of a state. They give no rates and no recommendations, but they have a lower cost.
RamblaOptions.Default.CollectMetrics = true;
StateMetrics metrics = vm.Metrics;
Console.WriteLine($"{metrics.Mutations} mutations, {metrics.Notifications} notifications");The counters are disabled by default. Thus the write operation stays inexpensive.
Rambla — state for real-time .NET desktop applications · MIT · github.com/nicoseijas/Rambla · This wiki follows ASD-STE100.
Use Rambla
Reference