From 40564a73cea2ba70363ad5af013efc9aa7ba7e0f Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 24 Dec 2018 01:02:49 -0500 Subject: [PATCH] Core: use span to cut down on array copys --- Source/Game/Maps/TransportManager.cs | 3 +- .../Game/Movement/Generators/PathGenerator.cs | 3 +- .../SplineChainMovementGenerator.cs | 11 ++++--- Source/Game/Movement/Spline.cs | 30 +++++++++++-------- .../Game/Network/Packets/MovementPackets.cs | 5 ++-- Source/Game/Warden/WardenKeyGeneration.cs | 4 ++- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Source/Game/Maps/TransportManager.cs b/Source/Game/Maps/TransportManager.cs index 3a50480f9..420ab6cf1 100644 --- a/Source/Game/Maps/TransportManager.cs +++ b/Source/Game/Maps/TransportManager.cs @@ -203,7 +203,8 @@ namespace Game.Maps { int extra = !keyFrames[i - 1].Teleport ? 1 : 0; Spline spline = new Spline(); - spline.Init_Spline(splinePath.Skip(start).ToArray(), i - start + extra, Spline.EvaluationMode.Catmullrom); + Span span = splinePath.ToArray(); + spline.Init_Spline(span.Slice(start), i - start + extra, Spline.EvaluationMode.Catmullrom); spline.initLengths(); for (int j = start; j < i + extra; ++j) { diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index b1baaceac..1605f9bdb 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -634,9 +634,10 @@ namespace Game.Movement uint ns = 0; while (ns < nsteerPath) { + Span span = steerPath; // Stop at Off-Mesh link or when point is further than slop away. if ((steerPathFlags[ns].HasAnyFlag((byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) || - !InRangeYZX(steerPath.Skip((int)ns * 3).ToArray(), startPos, minTargetDist, 1000.0f))) + !InRangeYZX(span.Slice((int)ns * 3).ToArray(), startPos, minTargetDist, 1000.0f))) break; ns++; } diff --git a/Source/Game/Movement/Generators/SplineChainMovementGenerator.cs b/Source/Game/Movement/Generators/SplineChainMovementGenerator.cs index 78ec0f78b..804dfea55 100644 --- a/Source/Game/Movement/Generators/SplineChainMovementGenerator.cs +++ b/Source/Game/Movement/Generators/SplineChainMovementGenerator.cs @@ -45,9 +45,9 @@ namespace Game.Movement _msToNext = info.TimeToNext; } - uint SendPathSpline(Unit me, List wp) + uint SendPathSpline(Unit me, Span wp) { - int numWp = wp.Count; + int numWp = wp.Length; Cypher.Assert(numWp > 1, "Every path must have source & destination"); MoveSplineInit init = new MoveSplineInit(me); if (numWp > 2) @@ -64,7 +64,7 @@ namespace Game.Movement Log.outDebug(LogFilter.Movement, "{0}: Sending spline for {1}.", me.GetGUID().ToString(), index); SplineChainLink thisLink = _chain[index]; - uint actualDuration = SendPathSpline(me, thisLink.Points); + uint actualDuration = SendPathSpline(me, new Span(thisLink.Points.ToArray())); if (actualDuration != thisLink.ExpectedDuration) { Log.outDebug(LogFilter.Movement, "{0}: Sent spline for {1}, duration is {2} ms. Expected was {3} ms (delta {4} ms). Adjusting.", me.GetGUID().ToString(), index, actualDuration, thisLink.ExpectedDuration, actualDuration - thisLink.ExpectedDuration); @@ -90,9 +90,8 @@ namespace Game.Movement Log.outError(LogFilter.Movement, "{0}: Attempted to resume spline chain from invalid resume state ({1}, {2}).", me.GetGUID().ToString(), _nextIndex, _nextFirstWP); _nextFirstWP = (byte)(thisLink.Points.Count - 1); } - List partial = new List(); - partial.AddRange(thisLink.Points.Skip(_nextFirstWP - 1).ToArray()); - SendPathSpline(me, partial); + Span span = thisLink.Points.ToArray(); + SendPathSpline(me, span.Slice(_nextFirstWP - 1)); Log.outDebug(LogFilter.Movement, "{0}: Resumed spline chain generator from resume state.", me.GetGUID().ToString()); ++_nextIndex; if (_msToNext == 0) diff --git a/Source/Game/Movement/Spline.cs b/Source/Game/Movement/Spline.cs index 76ebdf9eb..448e233ae 100644 --- a/Source/Game/Movement/Spline.cs +++ b/Source/Game/Movement/Spline.cs @@ -64,12 +64,14 @@ namespace Game.Movement } void EvaluateCatmullRom(int index, float t, out Vector3 result) { - C_Evaluate(points.Skip(index - 1).ToArray(), t, s_catmullRomCoeffs, out result); + Span span = points; + C_Evaluate(span.Slice(index - 1), t, s_catmullRomCoeffs, out result); } void EvaluateBezier3(int index, float t, out Vector3 result) { index *= (int)3u; - C_Evaluate(points.Skip(index).ToArray(), t, s_Bezier3Coeffs, out result); + Span span = points; + C_Evaluate(span.Slice(index), t, s_Bezier3Coeffs, out result); } #endregion @@ -85,7 +87,7 @@ namespace Game.Movement Init_Spline(controls, count, m); } - public void Init_Spline(Vector3[] controls, int count, EvaluationMode m) + public void Init_Spline(Span controls, int count, EvaluationMode m) { m_mode = m; _cyclic = false; @@ -120,7 +122,7 @@ namespace Game.Movement index_lo = 0; index_hi = cyclic ? count : (count - 1); } - void InitCatmullRom(Vector3[] controls, int count, bool cyclic, int cyclic_point) + void InitCatmullRom(Span controls, int count, bool cyclic, int cyclic_point) { int real_size = count + (cyclic ? (1 + 2) : (1 + 1)); @@ -129,7 +131,7 @@ namespace Game.Movement int lo_index = 1; int high_index = lo_index + count - 1; - Array.Copy(controls, 0, points, lo_index, count); + Array.Copy(controls.ToArray(), 0, points, lo_index, count); // first and last two indexes are space for special 'virtual points' // these points are required for proper C_Evaluate and C_Evaluate_Derivative methtod work @@ -152,13 +154,13 @@ namespace Game.Movement index_lo = lo_index; index_hi = high_index + (cyclic ? 1 : 0); } - void InitBezier3(Vector3[] controls, int count, bool cyclic, int cyclic_point) + void InitBezier3(Span controls, int count, bool cyclic, int cyclic_point) { int c = (int)(count / 3u * 3u); int t = (int)(c / 3u); Array.Resize(ref points, c); - Array.Copy(controls, points, c); + Array.Copy(controls.ToArray(), points, c); index_lo = 0; index_hi = t - 1; @@ -190,12 +192,14 @@ namespace Game.Movement } void EvaluateDerivativeCatmullRom(int index, float t, out Vector3 result) { - C_Evaluate_Derivative(points.Skip(index - 1).ToArray(), t, s_catmullRomCoeffs, out result); + Span span = points; + C_Evaluate_Derivative(span.Slice(index - 1), t, s_catmullRomCoeffs, out result); } void EvaluateDerivativeBezier3(int index, float t, out Vector3 result) { index *= (int)3u; - C_Evaluate_Derivative(points.Skip(index).ToArray(), t, s_Bezier3Coeffs, out result); + Span span = points; + C_Evaluate_Derivative(span.Slice(index), t, s_Bezier3Coeffs, out result); } #endregion @@ -221,7 +225,7 @@ namespace Game.Movement float SegLengthCatmullRom(int index) { Vector3 nextPos; - var p = points.Skip(index - 1).ToArray(); + Span p = points.AsSpan(index - 1); Vector3 curPos = nextPos = p[1]; int i = 1; @@ -240,7 +244,7 @@ namespace Game.Movement index *= (int)3u; Vector3 nextPos; - var p = points.Skip(index).ToArray(); + Span p = points.AsSpan(index); C_Evaluate(p, 0.0f, s_Bezier3Coeffs, out nextPos); Vector3 curPos = nextPos; @@ -297,7 +301,7 @@ namespace Game.Movement private static readonly Matrix4 s_Bezier3Coeffs = new Matrix4(-1.0f, 3.0f, -3.0f, 1.0f, 3.0f, -6.0f, 3.0f, 0.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f); - void C_Evaluate(Vector3[] vertice, float t, Matrix4 matr, out Vector3 result) + void C_Evaluate(Span vertice, float t, Matrix4 matr, out Vector3 result) { Vector4 tvec = new Vector4(t * t * t, t * t, t, 1.0f); Vector4 weights = (tvec * matr); @@ -305,7 +309,7 @@ namespace Game.Movement result = vertice[0] * weights[0] + vertice[1] * weights[1] + vertice[2] * weights[2] + vertice[3] * weights[3]; } - void C_Evaluate_Derivative(Vector3[] vertice, float t, Matrix4 matr, out Vector3 result) + void C_Evaluate_Derivative(Span vertice, float t, Matrix4 matr, out Vector3 result) { Vector4 tvec = new Vector4(3.0f * t * t, 2.0f * t, 1.0f, 0.0f); Vector4 weights = (tvec * matr); diff --git a/Source/Game/Network/Packets/MovementPackets.cs b/Source/Game/Network/Packets/MovementPackets.cs index 384a6c7fd..37fe7b247 100644 --- a/Source/Game/Network/Packets/MovementPackets.cs +++ b/Source/Game/Network/Packets/MovementPackets.cs @@ -22,6 +22,7 @@ using Game.Entities; using Game.Movement; using System.Collections.Generic; using System.Linq; +using System; namespace Game.Network.Packets { @@ -363,7 +364,7 @@ namespace Game.Network.Packets else { int lastIdx = spline.getPointCount() - 3; - Vector3[] realPath = spline.getPoints().Skip(1).ToArray(); + Span realPath = new Span(spline.getPoints()).Slice(1); movementSpline.Points.Add(realPath[lastIdx]); @@ -372,7 +373,7 @@ namespace Game.Network.Packets Vector3 middle = (realPath[0] + realPath[lastIdx]) / 2.0f; // first and last points already appended - for (uint i = 1; i < lastIdx; ++i) + for (int i = 1; i < lastIdx; ++i) movementSpline.PackedDeltas.Add(middle - realPath[i]); } } diff --git a/Source/Game/Warden/WardenKeyGeneration.cs b/Source/Game/Warden/WardenKeyGeneration.cs index dbf1dfd08..a3b99d7b7 100644 --- a/Source/Game/Warden/WardenKeyGeneration.cs +++ b/Source/Game/Warden/WardenKeyGeneration.cs @@ -17,6 +17,7 @@ using System.Linq; using System.Security.Cryptography; +using System; namespace Game { @@ -25,12 +26,13 @@ namespace Game public SHA1Randx(byte[] buff) { int halfSize = buff.Length / 2; + Span span = buff; sh = SHA1.Create(); o1 = sh.ComputeHash(buff, 0, halfSize); sh = SHA1.Create(); - o2 = sh.ComputeHash(buff.Skip(halfSize).ToArray(), 0, buff.Length - halfSize); + o2 = sh.ComputeHash(span.Slice(halfSize).ToArray(), 0, buff.Length - halfSize); FillUp(); }