Fix the sensor monitoring console forcing a GC every 3 seconds (#38146)

* Optimize sensor monitoring window graph drawing

* Add shared static Vector2 pool for all GraphView instances

* Address requested changes

* remove lock
This commit is contained in:
ArtisticRoomba
2025-06-27 04:37:00 -07:00
committed by GitHub
parent d7d83bd87c
commit 1d2907fb4e

View File

@@ -25,6 +25,29 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
private TimeSpan _retentionTime; private TimeSpan _retentionTime;
private readonly Dictionary<int, SensorData> _sensorData = new(); private readonly Dictionary<int, SensorData> _sensorData = new();
/// <summary>
/// <para>A shared array used to store vertices for drawing graphs in <see cref="GraphView"/>.
/// Prevents excessive allocations by reusing the same array across multiple graph views.</para>
/// <para>This effectively makes it so that each <see cref="SensorMonitoringWindow"/> has its own pooled array.</para>
/// </summary>
private Vector2[] _sharedVertices = [];
/// <summary>
/// Retrieves a shared array of vertices, ensuring that it has at least the requested size.
/// Assigns a new array of the requested size if the current shared array is smaller than the requested size.
/// </summary>
/// <param name="requestedSize">The minimum number of vertices required in the shared array.</param>
/// <returns>An array of <see cref="System.Numerics.Vector2"/> representing the shared vertices.</returns>
/// <remarks>This does not prevent other threads from accessing the same shared pool.</remarks>
public Vector2[] GetSharedVertices(int requestedSize)
{
if (_sharedVertices.Length < requestedSize)
{
_sharedVertices = new Vector2[requestedSize];
}
return _sharedVertices;
}
public SensorMonitoringWindow() public SensorMonitoringWindow()
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
@@ -145,7 +168,7 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
} }
}); });
Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f) { MinHeight = 150 }); Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f, this) { MinHeight = 150 });
Asdf.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } }); Asdf.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } });
} }
} }
@@ -197,14 +220,20 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
private readonly TimeSpan _startTime; private readonly TimeSpan _startTime;
private readonly TimeSpan _curTime; private readonly TimeSpan _curTime;
private readonly float _maxY; private readonly float _maxY;
private readonly SensorMonitoringWindow _parentWindow;
public GraphView(Queue<SensorSample> samples, TimeSpan startTime, TimeSpan curTime, float maxY) public GraphView(Queue<SensorSample> samples,
TimeSpan startTime,
TimeSpan curTime,
float maxY,
SensorMonitoringWindow parentWindow)
{ {
_samples = samples; _samples = samples;
_startTime = startTime; _startTime = startTime;
_curTime = curTime; _curTime = curTime;
_maxY = maxY; _maxY = maxY;
RectClipContent = true; RectClipContent = true;
_parentWindow = parentWindow;
} }
protected override void Draw(DrawingHandleScreen handle) protected override void Draw(DrawingHandleScreen handle)
@@ -212,12 +241,12 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
base.Draw(handle); base.Draw(handle);
var window = (float)(_curTime - _startTime).TotalSeconds; var window = (float)(_curTime - _startTime).TotalSeconds;
// TODO: omg this is terrible don't fucking hardcode this size to something uncached huge omfg.
var vertices = new Vector2[25000];
var countVtx = 0; var countVtx = 0;
var lastPoint = new Vector2(float.NaN, float.NaN); var lastPoint = new Vector2(float.NaN, float.NaN);
var requiredVertices = 6 * (_samples.Count - 1);
var vertices = _parentWindow.GetSharedVertices(requiredVertices);
foreach (var (time, sample) in _samples) foreach (var (time, sample) in _samples)
{ {
@@ -242,8 +271,9 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
lastPoint = newPoint; lastPoint = newPoint;
} }
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList,
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList, vertices.AsSpan(0, countVtx), Color.White.WithAlpha(0.1f)); vertices.AsSpan(0, countVtx),
Color.White.WithAlpha(0.1f));
} }
} }
} }