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 91b0d43 commit 1970ec5
Show file tree
Hide file tree
Showing 3 changed files with 26 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
42 changes: 26 additions & 16 deletions Assets/Mirror/Core/NetworkIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -974,9 +974,20 @@ 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();
}
}
}

// clear dirty component bits as well.
// otherwise OnBecameDirty wouldn't detect initial dirty next time.
serverOwnerDirtyMask = 0;
serverObserversDirtyMask = 0;
}

// serialize components into writer on the client.
Expand Down Expand Up @@ -1023,9 +1034,19 @@ 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();
}
}
}

// clear dirty component bits as well.
// otherwise OnBecameDirty wouldn't detect initial dirty next time.
clientDirtyMask = 0;
}

// deserialize components from the client on the server.
Expand Down Expand Up @@ -1112,21 +1133,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 +1336,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 1970ec5

Please sign in to comment.