Skip to content

Commit

Permalink
perf: removing allocation from SendToAll
Browse files Browse the repository at this point in the history
Casting to IEnumerable will cause the Enumerator to be boxed. Using  while loop instead avoids this.
  • Loading branch information
James-Frowen committed Apr 27, 2022
1 parent de935b0 commit 6166244
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion Assets/Mirage/Runtime/NetworkServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,32 @@ internal void InvokeLocalConnected()
public void SendToAll<T>(T msg, int channelId = Channel.Reliable)
{
if (logger.LogEnabled()) logger.Log("Server.SendToAll id:" + typeof(T));
SendToMany(Players, msg, channelId);

using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
// pack message into byte[] once
MessagePacker.Pack(msg, writer);
var segment = writer.ToArraySegment();
int count = 0;

// using SendToMany (with IEnumerable) will cause Enumerator to be boxed and create GC/alloc
// instead we can use while loop and MoveNext to avoid boxing
Dictionary<IConnection, INetworkPlayer>.ValueCollection.Enumerator enumerator = connections.Values.GetEnumerator();
while (enumerator.MoveNext())
{
INetworkPlayer player = enumerator.Current;
player.Send(segment, channelId);
count++;
}
enumerator.Dispose();

NetworkDiagnostics.OnSend(msg, segment.Count, count);
}
}

/// <summary>
/// Sends a message to many connections
/// <para>WARNING: using this method <b>may</b> cause Enumerator to be boxed creating GC/alloc. Use <see cref="SendToMany{T}(IReadOnlyList{INetworkPlayer}, T, int)"/> version where possible</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="players"></param>
Expand Down

0 comments on commit 6166244

Please sign in to comment.