optimization: MinBy and MaxBy instead of sorting

This commit is contained in:
JohnCorby 2022-02-15 20:56:16 -08:00
parent 76593a11bf
commit 83bec7b75f
5 changed files with 76 additions and 12 deletions

View File

@ -68,8 +68,8 @@ namespace QSB.DeathSync
else
{
var allAstroobjects = QSBWorldSync.GetUnityObjects<AstroObject>().Where(x => x.GetAstroObjectName() != AstroObject.Name.None && x.GetAstroObjectType() != AstroObject.Type.Satellite);
var ordered = allAstroobjects.OrderBy(x => Vector3.SqrMagnitude(x.transform.position));
DeathClosestAstroObject = ordered.First().transform;
var closest = allAstroobjects.MinBy(x => Vector3.SqrMagnitude(x.transform.position));
DeathClosestAstroObject = closest.transform;
}
var deathPosition = Locator.GetPlayerTransform().position;

View File

@ -94,8 +94,8 @@ namespace QSB.Player
=> PlayerList.ForEach(x => x.SetVisible(false, 2));
public static PlayerInfo GetClosestPlayerToWorldPoint(Vector3 worldPoint, bool includeLocalPlayer) => includeLocalPlayer
? GetClosestPlayerToWorldPoint(PlayerList, worldPoint)
: GetClosestPlayerToWorldPoint(PlayerList.Where(x => x != LocalPlayer).ToList(), worldPoint);
? GetClosestPlayerToWorldPoint(PlayerList, worldPoint)
: GetClosestPlayerToWorldPoint(PlayerList.Where(x => x != LocalPlayer).ToList(), worldPoint);
public static PlayerInfo GetClosestPlayerToWorldPoint(List<PlayerInfo> playerList, Vector3 worldPoint)
{
@ -105,16 +105,18 @@ namespace QSB.Player
return null;
}
playerList = playerList.Where(x => x.IsReady && x.Body != null).ToList();
if (playerList.Count == 0)
{
DebugLog.ToConsole($"Error - Cannot get closest player from empty player list.", MessageType.Error);
DebugLog.ToConsole($"Error - Cannot get closest player from empty (ready) player list.", MessageType.Error);
return null;
}
return playerList.Where(x => x.IsReady && x.Body != null).OrderBy(x => Vector3.Distance(x.Body.transform.position, worldPoint)).FirstOrDefault();
return playerList.MinBy(x => Vector3.Distance(x.Body.transform.position, worldPoint));
}
public static IEnumerable<Tuple<PlayerInfo, IQSBItem>> GetPlayerCarryItems()
=> PlayerList.Select(x => new Tuple<PlayerInfo, IQSBItem>(x, x.HeldItem));
}
}
}

View File

@ -120,7 +120,7 @@ namespace QSB.SectorSync
}
var closest = goodSectors
.OrderBy(sector => CalculateSectorScore(sector, _sectorDetector._attachedRigidbody)).First();
.MinBy(sector => CalculateSectorScore(sector, _sectorDetector._attachedRigidbody));
if (inASector)
{

View File

@ -138,7 +138,7 @@ namespace QSB.Syncs
// and use the closest one
_player = QSBPlayerManager.PlayerList
.Where(x => x.PlayerId <= netId)
.OrderBy(x => x.PlayerId).Last();
.MaxBy(x => x.PlayerId);
}
DontDestroyOnLoad(gameObject);

View File

@ -19,15 +19,17 @@ namespace QSB.Utility
public static GameObject InstantiateInactive(this GameObject original)
{
if (!original.activeSelf)
{
return Object.Instantiate(original);
}
original.SetActive(false);
var copy = Object.Instantiate(original);
original.SetActive(true);
return copy;
}
public static Transform InstantiateInactive(this Transform original) =>
original.gameObject.InstantiateInactive().transform;
#endregion
#region MIRROR
@ -94,6 +96,66 @@ namespace QSB.Utility
}
}
public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var comparer = Comparer<TKey>.Default;
var yk = default(TKey);
var y = default(TSource);
var hasValue = false;
foreach (var x in source)
{
var xk = keySelector(x);
if (!hasValue)
{
hasValue = true;
yk = xk;
y = x;
}
else if (comparer.Compare(xk, yk) < 0)
{
yk = xk;
y = x;
}
}
if (!hasValue)
{
throw new InvalidOperationException("Sequence contains no elements");
}
return y;
}
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var comparer = Comparer<TKey>.Default;
var yk = default(TKey);
var y = default(TSource);
var hasValue = false;
foreach (var x in source)
{
var xk = keySelector(x);
if (!hasValue)
{
hasValue = true;
yk = xk;
y = x;
}
else if (comparer.Compare(xk, yk) > 0)
{
yk = xk;
y = x;
}
}
if (!hasValue)
{
throw new InvalidOperationException("Sequence contains no elements");
}
return y;
}
public static int IndexOf<T>(this T[] array, T value) => Array.IndexOf(array, value);
public static bool IsInRange<T>(this IList<T> list, int index) => index >= 0 && index < list.Count;