Skip to content

Commit

Permalink
perf: NetworkIdentity.Serialize now clears dirty bits while iterating…
Browse files Browse the repository at this point in the history
…. avoids O(N) ClearALlComponentsDirtyBits call after each Serialize call.
  • Loading branch information
vis2k committed Nov 13, 2022
1 parent 1315d17 commit 484c97e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 22 deletions.
3 changes: 0 additions & 3 deletions Assets/Mirror/Core/NetworkClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,9 +1493,6 @@ static void Broadcast()
payload = writer.ToArraySegment()
};
Send(message);

// reset dirty bits so it's not resent next time.
identity.ClearAllComponentsDirtyBits();
}
}
}
Expand Down
33 changes: 17 additions & 16 deletions Assets/Mirror/Core/NetworkIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,12 @@ internal void SerializeServer(bool initialState, NetworkWriter ownerWriter, Netw
if (ownerDirty) ownerWriter.WriteBytes(segment.Array, segment.Offset, segment.Count);
if (observersDirty) observersWriter.WriteBytes(segment.Array, segment.Offset, segment.Count);
}

// clear dirty bits after serializing.
// best to do it here while iterating.
// ClearAllComponentsDirtyBits would have to iterate
// everything again otherwise.
comp.ClearAllDirtyBits();
}
}
}
Expand Down Expand Up @@ -1023,6 +1029,12 @@ internal void SerializeClient(NetworkWriter writer)
// serialize into writer.
// server always knows initialState, we never need to send it
comp.Serialize(writer, false);

// clear dirty bits after serializing.
// best to do it here while iterating.
// ClearAllComponentsDirtyBits would have to iterate
// everything again otherwise.
comp.ClearAllDirtyBits();
}
}
}
Expand Down Expand Up @@ -1112,21 +1124,6 @@ internal NetworkIdentitySerialization GetServerSerializationAtTick(int tick)
lastSerialization.ownerWriter,
lastSerialization.observersWriter);

// clear dirty bits for the components that we serialized.
// previously we did this in NetworkServer.BroadcastToConnection
// for every connection, for every entity.
// but we only serialize each entity once, right here in this
// 'lastSerialization.tick != tick' scope.
// so only do it once.
//
// NOTE: not in Serializell as that should only do one
// thing: serialize data.
//
// NOTE: this used to be very important to avoid ever growing
// SyncList changes if they had no observers, but we've
// added SyncObject.isRecording since.
ClearAllComponentsDirtyBits();

// set tick
lastSerialization.tick = tick;
//Debug.Log($"{name} (netId={netId}) serialized for tick={tickTimeStamp}");
Expand Down Expand Up @@ -1330,13 +1327,17 @@ internal void Reset()
isLocalPlayer = false;
}

// clear all component's dirty bits no matter what
// clear all component's dirty bits no matter what.
// when serializing, it's best to clear them while already iterating.
// this way we don't need to iterate all components here again.
// this should only be used if we need to clear outside of serialization.
internal void ClearAllComponentsDirtyBits()
{
serverOwnerDirtyMask = 0;
serverObserversDirtyMask = 0;
clientDirtyMask = 0;

// TODO clear only the dirty ones? fine now without interval.
foreach (NetworkBehaviour comp in NetworkBehaviours)
{
comp.ClearAllDirtyBits();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,6 @@ public void SerializeServer_ObserversMode_ClientToServer()
Assert.That(ownerWriter.Position, Is.GreaterThan(0));
Assert.That(observersWriter.Position, Is.GreaterThan(0));

// reset dirty bits after serializing
identity.ClearAllComponentsDirtyBits();

// delta: should only write for observers
++comp.value; // change something
ownerWriter.Position = 0;
Expand Down

0 comments on commit 484c97e

Please sign in to comment.