diff --git a/Assets/Mirror/Core/NetworkReaderExtensions.cs b/Assets/Mirror/Core/NetworkReaderExtensions.cs index 4493be3db..842470df9 100644 --- a/Assets/Mirror/Core/NetworkReaderExtensions.cs +++ b/Assets/Mirror/Core/NetworkReaderExtensions.cs @@ -33,17 +33,34 @@ public static class NetworkReaderExtensions public static ushort ReadUShort(this NetworkReader reader) => reader.ReadBlittable(); public static ushort? ReadUShortNullable(this NetworkReader reader) => reader.ReadBlittableNullable(); - public static int ReadInt(this NetworkReader reader) => reader.ReadBlittable(); - public static int? ReadIntNullable(this NetworkReader reader) => reader.ReadBlittableNullable(); + // integer bandwidth optimization: write all ints as varint! + // reduces bandwidth for almost all integers. + // increaes bandwidth for very few large integers like hashes. + // => very much worth it for Mirror (see Benchmarks) + // => very much worth it for users (they won't have to compress manually) + public static int ReadInt(this NetworkReader reader) => (int)Compression.DecompressVarInt(reader); + public static int? ReadIntNullable(this NetworkReader reader) + { + return reader.ReadBool() ? (int)Compression.DecompressVarInt(reader) : default; + } - public static uint ReadUInt(this NetworkReader reader) => reader.ReadBlittable(); - public static uint? ReadUIntNullable(this NetworkReader reader) => reader.ReadBlittableNullable(); + public static uint ReadUInt(this NetworkReader reader) => (uint)Compression.DecompressVarUInt(reader); + public static uint? ReadUIntNullable(this NetworkReader reader) + { + return reader.ReadBool() ? (uint)Compression.DecompressVarUInt(reader) : default; + } - public static long ReadLong(this NetworkReader reader) => reader.ReadBlittable(); - public static long? ReadLongNullable(this NetworkReader reader) => reader.ReadBlittableNullable(); + public static long ReadLong(this NetworkReader reader) => Compression.DecompressVarInt(reader); + public static long? ReadLongNullable(this NetworkReader reader) + { + return reader.ReadBool() ? Compression.DecompressVarInt(reader) : default; + } - public static ulong ReadULong(this NetworkReader reader) => reader.ReadBlittable(); - public static ulong? ReadULongNullable(this NetworkReader reader) => reader.ReadBlittableNullable(); + public static ulong ReadULong(this NetworkReader reader) => Compression.DecompressVarUInt(reader); + public static ulong? ReadULongNullable(this NetworkReader reader) + { + return reader.ReadBool() ? Compression.DecompressVarUInt(reader) : default; + } public static float ReadFloat(this NetworkReader reader) => reader.ReadBlittable(); public static float? ReadFloatNullable(this NetworkReader reader) => reader.ReadBlittableNullable(); diff --git a/Assets/Mirror/Core/NetworkWriterExtensions.cs b/Assets/Mirror/Core/NetworkWriterExtensions.cs index fef9f613a..251a5d3a3 100644 --- a/Assets/Mirror/Core/NetworkWriterExtensions.cs +++ b/Assets/Mirror/Core/NetworkWriterExtensions.cs @@ -28,17 +28,38 @@ public static class NetworkWriterExtensions public static void WriteUShort(this NetworkWriter writer, ushort value) => writer.WriteBlittable(value); public static void WriteUShortNullable(this NetworkWriter writer, ushort? value) => writer.WriteBlittableNullable(value); - public static void WriteInt(this NetworkWriter writer, int value) => writer.WriteBlittable(value); - public static void WriteIntNullable(this NetworkWriter writer, int? value) => writer.WriteBlittableNullable(value); + // integer bandwidth optimization: write all ints as varint! + // reduces bandwidth for almost all integers. + // increaes bandwidth for very few large integers like hashes. + // => very much worth it for Mirror (see Benchmarks) + // => very much worth it for users (they won't have to compress manually) + public static void WriteInt(this NetworkWriter writer, int value) => Compression.CompressVarInt(writer, value); + public static void WriteIntNullable(this NetworkWriter writer, int? value) + { + writer.WriteBool(value.HasValue); + if (value.HasValue) WriteInt(writer, value.Value); + } - public static void WriteUInt(this NetworkWriter writer, uint value) => writer.WriteBlittable(value); - public static void WriteUIntNullable(this NetworkWriter writer, uint? value) => writer.WriteBlittableNullable(value); + public static void WriteUInt(this NetworkWriter writer, uint value) => Compression.CompressVarUInt(writer, value); + public static void WriteUIntNullable(this NetworkWriter writer, uint? value) + { + writer.WriteBool(value.HasValue); + if (value.HasValue) WriteUInt(writer, value.Value); + } - public static void WriteLong(this NetworkWriter writer, long value) => writer.WriteBlittable(value); - public static void WriteLongNullable(this NetworkWriter writer, long? value) => writer.WriteBlittableNullable(value); + public static void WriteLong(this NetworkWriter writer, long value) => Compression.CompressVarInt(writer, value); + public static void WriteLongNullable(this NetworkWriter writer, long? value) + { + writer.WriteBool(value.HasValue); + if (value.HasValue) WriteLong(writer, value.Value); + } - public static void WriteULong(this NetworkWriter writer, ulong value) => writer.WriteBlittable(value); - public static void WriteULongNullable(this NetworkWriter writer, ulong? value) => writer.WriteBlittableNullable(value); + public static void WriteULong(this NetworkWriter writer, ulong value) => Compression.CompressVarUInt(writer, value); + public static void WriteULongNullable(this NetworkWriter writer, ulong? value) + { + writer.WriteBool(value.HasValue); + if (value.HasValue) WriteULong(writer, value.Value); + } public static void WriteFloat(this NetworkWriter writer, float value) => writer.WriteBlittable(value); public static void WriteFloatNullable(this NetworkWriter writer, float? value) => writer.WriteBlittableNullable(value); diff --git a/Assets/Mirror/Core/Tools/Compression.cs b/Assets/Mirror/Core/Tools/Compression.cs index d04b566b1..845d16507 100644 --- a/Assets/Mirror/Core/Tools/Compression.cs +++ b/Assets/Mirror/Core/Tools/Compression.cs @@ -318,7 +318,6 @@ public static void CompressVarUInt(NetworkWriter writer, ulong value) { // straight forward implementation: // keep this for understanding & debugging. - /* if (value <= 240) { writer.WriteByte((byte)value); @@ -400,11 +399,12 @@ public static void CompressVarUInt(NetworkWriter writer, ulong value) writer.WriteByte((byte)((value >> 48) & 0xFF)); writer.WriteByte((byte)((value >> 56) & 0xFF)); } - */ + // DISABLED: WriteInt() always calls WriteVarInt, so we can't recurse to WriteInt here // faster implementation writes multiple bytes at once. // avoids extra Space, WriteBlittable overhead. // VarInt is in hot path, performance matters here. + /* if (value <= 240) { byte a = (byte)value; @@ -474,7 +474,7 @@ public static void CompressVarUInt(NetworkWriter writer, ulong value) { writer.WriteByte(255); writer.WriteULong(value); - } + }*/ } // zigzag encoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba