Skip to content

Commit

Permalink
Avoid byte[] allocation in string/symbol encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
xinchen10 committed Apr 10, 2023
1 parent 8ef78dc commit 83dcc6d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 40 deletions.
44 changes: 25 additions & 19 deletions Microsoft.Azure.Amqp/Amqp/Encoding/StringEncoding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,23 @@ public static void Encode(string value, ByteBuffer buffer)
}
else
{
byte[] encodedData = Encoding.UTF8.GetBytes(value);
int encodeWidth = AmqpEncoding.GetEncodeWidthBySize(encodedData.Length);
AmqpBitConverter.WriteUByte(buffer, encodeWidth == FixedWidth.UByte ? FormatCode.String8Utf8 : FormatCode.String32Utf8);
StringEncoding.Encode(encodedData, encodeWidth, buffer);
int stringSize = Encoding.UTF8.GetByteCount(value);
int encodeWidth = AmqpEncoding.GetEncodeWidthBySize(stringSize);
if (encodeWidth == FixedWidth.UByte)
{
AmqpBitConverter.WriteUByte(buffer, FormatCode.String8Utf8);
AmqpBitConverter.WriteUByte(buffer, (byte)stringSize);
}
else
{
AmqpBitConverter.WriteUByte(buffer, FormatCode.String32Utf8);
AmqpBitConverter.WriteUInt(buffer, (uint)stringSize);
}

buffer.Validate(true, stringSize);
int bytes = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer.Buffer, buffer.WritePos);
Fx.Assert(bytes == stringSize, "size wrong");
buffer.Append(stringSize);
}
}

Expand Down Expand Up @@ -85,7 +98,14 @@ public override void EncodeObject(object value, bool arrayEncoding, ByteBuffer b
{
if (arrayEncoding)
{
StringEncoding.Encode(Encoding.UTF8.GetBytes((string)value), FixedWidth.UInt, buffer);
string strValue = (string)value;
int stringSize = Encoding.UTF8.GetByteCount(strValue);
AmqpBitConverter.WriteUInt(buffer, (uint)stringSize);

buffer.Validate(true, stringSize);
int bytes = Encoding.UTF8.GetBytes(strValue, 0, strValue.Length, buffer.Buffer, buffer.WritePos);
Fx.Assert(bytes == stringSize, "size wrong");
buffer.Append(stringSize);
}
else
{
Expand All @@ -97,19 +117,5 @@ public override object DecodeObject(ByteBuffer buffer, FormatCode formatCode)
{
return StringEncoding.Decode(buffer, formatCode);
}

static void Encode(byte[] encodedData, int width, ByteBuffer buffer)
{
if (width == FixedWidth.UByte)
{
AmqpBitConverter.WriteUByte(buffer, (byte)encodedData.Length);
}
else
{
AmqpBitConverter.WriteUInt(buffer, (uint)encodedData.Length);
}

AmqpBitConverter.WriteBytes(buffer, encodedData, 0, encodedData.Length);
}
}
}
46 changes: 25 additions & 21 deletions Microsoft.Azure.Amqp/Amqp/Encoding/SymbolEncoding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

namespace Microsoft.Azure.Amqp.Encoding
{
using System.Text;

sealed class SymbolEncoding : EncodingBase
{
public SymbolEncoding()
Expand Down Expand Up @@ -32,10 +30,23 @@ public static void Encode(AmqpSymbol value, ByteBuffer buffer)
}
else
{
byte[] encodedData = SystemEncoding.ASCII.GetBytes(value.Value);
int encodeWidth = AmqpEncoding.GetEncodeWidthBySize(encodedData.Length);
AmqpBitConverter.WriteUByte(buffer, encodeWidth == FixedWidth.UByte ? FormatCode.Symbol8 : FormatCode.Symbol32);
SymbolEncoding.Encode(encodedData, encodeWidth, buffer);
int stringSize = SystemEncoding.ASCII.GetByteCount(value.Value);
int encodeWidth = AmqpEncoding.GetEncodeWidthBySize(stringSize);
if (encodeWidth == FixedWidth.UByte)
{
AmqpBitConverter.WriteUByte(buffer, FormatCode.Symbol8);
AmqpBitConverter.WriteUByte(buffer, (byte)stringSize);
}
else
{
AmqpBitConverter.WriteUByte(buffer, FormatCode.Symbol32);
AmqpBitConverter.WriteUInt(buffer, (uint)stringSize);
}

buffer.Validate(true, stringSize);
int bytes = SystemEncoding.ASCII.GetBytes(value.Value, 0, value.Value.Length, buffer.Buffer, buffer.WritePos);
Fx.Assert(bytes == stringSize, "size wrong");
buffer.Append(stringSize);
}
}

Expand Down Expand Up @@ -70,7 +81,14 @@ public override void EncodeObject(object value, bool arrayEncoding, ByteBuffer b
{
if (arrayEncoding)
{
SymbolEncoding.Encode(SystemEncoding.ASCII.GetBytes(((AmqpSymbol)value).Value), FixedWidth.UInt, buffer);
string strValue = ((AmqpSymbol)value).Value;
int stringSize = SystemEncoding.ASCII.GetByteCount(strValue);
AmqpBitConverter.WriteUInt(buffer, (uint)stringSize);

buffer.Validate(true, stringSize);
int bytes = SystemEncoding.ASCII.GetBytes(strValue, 0, strValue.Length, buffer.Buffer, buffer.WritePos);
Fx.Assert(bytes == stringSize, "size wrong");
buffer.Append(stringSize);
}
else
{
Expand All @@ -82,19 +100,5 @@ public override object DecodeObject(ByteBuffer buffer, FormatCode formatCode)
{
return SymbolEncoding.Decode(buffer, formatCode);
}

static void Encode(byte[] encodedData, int width, ByteBuffer buffer)
{
if (width == FixedWidth.UByte)
{
AmqpBitConverter.WriteUByte(buffer, (byte)encodedData.Length);
}
else
{
AmqpBitConverter.WriteUInt(buffer, (uint)encodedData.Length);
}

AmqpBitConverter.WriteBytes(buffer, encodedData, 0, encodedData.Length);
}
}
}

0 comments on commit 83dcc6d

Please sign in to comment.