mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-18 10:26:11 +08:00
Performance refactoring.
This commit is contained in:
@@ -9,6 +9,7 @@ namespace MQTTnet.AspNetCore
|
||||
public class SpanBasedMqttPacketBodyReader : IMqttPacketBodyReader
|
||||
{
|
||||
private ReadOnlyMemory<byte> _buffer;
|
||||
|
||||
private int _offset;
|
||||
|
||||
public void SetBuffer(ReadOnlyMemory<byte> buffer)
|
||||
@@ -17,11 +18,11 @@ namespace MQTTnet.AspNetCore
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
public ulong Length => (ulong)_buffer.Length;
|
||||
public int Length => _buffer.Length;
|
||||
|
||||
public bool EndOfStream => _buffer.Length.Equals(_offset);
|
||||
|
||||
public ulong Offset => (ulong)_offset;
|
||||
public int Offset => _offset;
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
@@ -116,9 +117,9 @@ namespace MQTTnet.AspNetCore
|
||||
throw new MqttProtocolViolationException("Boolean values can be 0 or 1 only.");
|
||||
}
|
||||
|
||||
public void Seek(ulong position)
|
||||
public void Seek(int position)
|
||||
{
|
||||
_offset = (int)position;
|
||||
_offset = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ namespace MQTTnet.Formatter
|
||||
{
|
||||
public interface IMqttPacketBodyReader
|
||||
{
|
||||
ulong Length { get; }
|
||||
int Length { get; }
|
||||
|
||||
ulong Offset { get; }
|
||||
int Offset { get; }
|
||||
|
||||
bool EndOfStream { get; }
|
||||
|
||||
@@ -26,6 +26,6 @@ namespace MQTTnet.Formatter
|
||||
|
||||
bool ReadBoolean();
|
||||
|
||||
void Seek(ulong position);
|
||||
void Seek(int position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,52 +9,54 @@ namespace MQTTnet.Formatter
|
||||
public class MqttPacketBodyReader : IMqttPacketBodyReader
|
||||
{
|
||||
private readonly byte[] _buffer;
|
||||
private readonly ulong _initialOffset;
|
||||
private readonly ulong _length;
|
||||
private readonly int _initialOffset;
|
||||
private readonly int _length;
|
||||
|
||||
private int _offset;
|
||||
|
||||
public MqttPacketBodyReader(byte[] buffer, int offset, int length)
|
||||
: this(buffer, (ulong)offset, (ulong)length)
|
||||
{
|
||||
}
|
||||
|
||||
public MqttPacketBodyReader(byte[] buffer, ulong offset, ulong length)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_initialOffset = offset;
|
||||
Offset = offset;
|
||||
_offset = offset;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public ulong Offset { get; private set; }
|
||||
|
||||
public ulong Length => _length - Offset;
|
||||
|
||||
public bool EndOfStream => Offset == _length;
|
||||
|
||||
public void Seek(ulong position)
|
||||
public int Offset
|
||||
{
|
||||
Offset = _initialOffset + position;
|
||||
get => _offset;
|
||||
}
|
||||
|
||||
public ArraySegment<byte> Read(uint length)
|
||||
public int Length => _length - _offset;
|
||||
|
||||
public bool EndOfStream => _offset == _length;
|
||||
|
||||
public void Seek(int position)
|
||||
{
|
||||
_offset = _initialOffset + position;
|
||||
}
|
||||
|
||||
public ArraySegment<byte> Read(int length)
|
||||
{
|
||||
ValidateReceiveBuffer(length);
|
||||
|
||||
var buffer = new ArraySegment<byte>(_buffer, (int)Offset, (int)length);
|
||||
Offset += length;
|
||||
var buffer = new ArraySegment<byte>(_buffer, (int)_offset, (int)length);
|
||||
_offset += length;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
ValidateReceiveBuffer(1);
|
||||
return _buffer[Offset++];
|
||||
|
||||
return _buffer[_offset++];
|
||||
}
|
||||
|
||||
public bool ReadBoolean()
|
||||
{
|
||||
ValidateReceiveBuffer(1);
|
||||
var buffer = _buffer[Offset++];
|
||||
|
||||
var buffer = _buffer[_offset++];
|
||||
|
||||
if (buffer == 0)
|
||||
{
|
||||
@@ -71,15 +73,15 @@ namespace MQTTnet.Formatter
|
||||
|
||||
public byte[] ReadRemainingData()
|
||||
{
|
||||
return new ArraySegment<byte>(_buffer, (int)Offset, (int)(_length - Offset)).ToArray();
|
||||
return new ArraySegment<byte>(_buffer, (int)_offset, (int)(_length - _offset)).ToArray();
|
||||
}
|
||||
|
||||
public ushort ReadTwoByteInteger()
|
||||
{
|
||||
ValidateReceiveBuffer(2);
|
||||
|
||||
var msb = _buffer[Offset++];
|
||||
var lsb = _buffer[Offset++];
|
||||
var msb = _buffer[_offset++];
|
||||
var lsb = _buffer[_offset++];
|
||||
|
||||
return (ushort)(msb << 8 | lsb);
|
||||
}
|
||||
@@ -88,31 +90,14 @@ namespace MQTTnet.Formatter
|
||||
{
|
||||
ValidateReceiveBuffer(4);
|
||||
|
||||
var byte0 = _buffer[Offset++];
|
||||
var byte1 = _buffer[Offset++];
|
||||
var byte2 = _buffer[Offset++];
|
||||
var byte3 = _buffer[Offset++];
|
||||
var byte0 = _buffer[_offset++];
|
||||
var byte1 = _buffer[_offset++];
|
||||
var byte2 = _buffer[_offset++];
|
||||
var byte3 = _buffer[_offset++];
|
||||
|
||||
return (uint)(byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3);
|
||||
}
|
||||
|
||||
public byte[] ReadWithLengthPrefix()
|
||||
{
|
||||
return ReadSegmentWithLengthPrefix().ToArray();
|
||||
}
|
||||
|
||||
private ArraySegment<byte> ReadSegmentWithLengthPrefix()
|
||||
{
|
||||
var length = ReadTwoByteInteger();
|
||||
|
||||
ValidateReceiveBuffer(length);
|
||||
|
||||
var result = new ArraySegment<byte>(_buffer, (int)Offset, length);
|
||||
Offset += length;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public uint ReadVariableLengthInteger()
|
||||
{
|
||||
var multiplier = 1;
|
||||
@@ -134,13 +119,30 @@ namespace MQTTnet.Formatter
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public byte[] ReadWithLengthPrefix()
|
||||
{
|
||||
return ReadSegmentWithLengthPrefix().ToArray();
|
||||
}
|
||||
|
||||
private ArraySegment<byte> ReadSegmentWithLengthPrefix()
|
||||
{
|
||||
var length = ReadTwoByteInteger();
|
||||
|
||||
ValidateReceiveBuffer(length);
|
||||
|
||||
var result = new ArraySegment<byte>(_buffer, (int)_offset, length);
|
||||
_offset += length;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ValidateReceiveBuffer(uint length)
|
||||
private void ValidateReceiveBuffer(int length)
|
||||
{
|
||||
if (_length < Offset + length)
|
||||
if (_length < _offset + length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(_buffer), $"Expected at least {Offset + length} bytes but there are only {_length} bytes");
|
||||
throw new ArgumentOutOfRangeException(nameof(_buffer), $"Expected at least {_offset + length} bytes but there are only {_length} bytes");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace MQTTnet.Formatter.V5
|
||||
public class MqttV500PropertiesReader
|
||||
{
|
||||
private readonly IMqttPacketBodyReader _body;
|
||||
private readonly uint _length;
|
||||
private readonly ulong _targetOffset;
|
||||
private readonly int _length;
|
||||
private readonly int _targetOffset;
|
||||
|
||||
public MqttV500PropertiesReader(IMqttPacketBodyReader body)
|
||||
{
|
||||
@@ -18,7 +18,7 @@ namespace MQTTnet.Formatter.V5
|
||||
|
||||
if (!body.EndOfStream)
|
||||
{
|
||||
_length = body.ReadVariableLengthInteger();
|
||||
_length = (int)body.ReadVariableLengthInteger();
|
||||
}
|
||||
|
||||
_targetOffset = body.Offset + _length;
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace MQTTnet.Benchmarks
|
||||
|
||||
var receivedPacket = new ReceivedMqttPacket(
|
||||
header.Flags,
|
||||
new MqttPacketBodyReader(_serializedPacket.Array, (ulong)(_serializedPacket.Count - header.RemainingLength), (ulong)_serializedPacket.Array.Length), 0);
|
||||
new MqttPacketBodyReader(_serializedPacket.Array, _serializedPacket.Count - header.RemainingLength, _serializedPacket.Array.Length), 0);
|
||||
|
||||
_serializer.Decode(receivedPacket);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class Protocol_Tests
|
||||
{
|
||||
[TestMethod]
|
||||
public void Encode_Four_Byte_Integer()
|
||||
{
|
||||
for (uint i = 0; i < 268435455; i++)
|
||||
{
|
||||
var buffer = MqttPacketWriter.EncodeVariableLengthInteger(i);
|
||||
var reader = new MqttPacketBodyReader(buffer.Array, buffer.Offset, buffer.Count);
|
||||
|
||||
var checkValue = reader.ReadVariableLengthInteger();
|
||||
|
||||
Assert.AreEqual(i, checkValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user