perf: NetworkServer.Update avoid costly NetworkIdentity null check. Catch exception and log useful warning instead. This amounted to ~5% CPU in 4k monsters test before.

This commit is contained in:
vis2k 2020-10-08 14:40:58 +02:00
parent 31b07ae02f
commit 9bd1d92b8e

View File

@ -73,7 +73,7 @@ public static class NetworkServer
public static float disconnectInactiveTimeout = 60f; public static float disconnectInactiveTimeout = 60f;
/// <summary> /// <summary>
/// cache the Send(connectionIds) list to avoid allocating each time /// cache the Send(connectionIds) list to avoid allocating each time
/// </summary> /// </summary>
static readonly List<int> connectionIdsCache = new List<int>(); static readonly List<int> connectionIdsCache = new List<int>();
@ -217,7 +217,7 @@ public static bool RemoveConnection(int connectionId)
} }
/// <summary> /// <summary>
/// called by LocalClient to add itself. dont call directly. /// called by LocalClient to add itself. dont call directly.
/// </summary> /// </summary>
/// <param name="conn"></param> /// <param name="conn"></param>
internal static void SetLocalConnection(ULocalConnectionToClient conn) internal static void SetLocalConnection(ULocalConnectionToClient conn)
@ -514,16 +514,23 @@ public static void Update()
// update all server objects // update all server objects
foreach (KeyValuePair<uint, NetworkIdentity> kvp in NetworkIdentity.spawned) foreach (KeyValuePair<uint, NetworkIdentity> kvp in NetworkIdentity.spawned)
{ {
NetworkIdentity identity = kvp.Value; // try to update.
if (identity != null) // spawned might have null entries if the user made a mistake.
//
// IMPORTANT: do not check kvp.Value != null. this is way too
// costly due to Unity's custom null check
// instead, catch the exception if it happens.
// (see 4k benchmark).
try
{ {
identity.ServerUpdate(); kvp.Value.ServerUpdate();
} }
else // spawned list should have no null entries because we
// always call Remove in OnObjectDestroy everywhere.
// but if it does, we should let the user know how it happens
catch (NullReferenceException)
{ {
// spawned list should have no null entries because we Debug.LogWarning("Found 'null' entry in spawned list for netId=" + kvp.Key + ". Please call NetworkServer.Destroy to destroy networked objects. Don't use GameObject.Destroy.");
// always call Remove in OnObjectDestroy everywhere.
logger.LogWarning("Found 'null' entry in spawned list for netId=" + kvp.Key + ". Please call NetworkServer.Destroy to destroy networked objects. Don't use GameObject.Destroy.");
} }
} }
} }
@ -971,7 +978,7 @@ public static void SetClientNotReady(NetworkConnection conn)
} }
/// <summary> /// <summary>
/// default ready handler. /// default ready handler.
/// </summary> /// </summary>
/// <param name="conn"></param> /// <param name="conn"></param>
/// <param name="msg"></param> /// <param name="msg"></param>