Skip to content

Commit dbc9853

Browse files
Merge pull request #983 from stebet/benchmarkUpdates
Cleaning up and adding more benchmarks.
2 parents a418ee4 + 92c2be5 commit dbc9853

13 files changed

+309
-186
lines changed

projects/Benchmarks/Benchmarks.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<OutputType>Exe</OutputType>
55
<AssemblyOriginatorKeyFile>../rabbit.snk</AssemblyOriginatorKeyFile>
66
<SignAssembly>true</SignAssembly>
7-
<TargetFramework>netcoreapp3.1</TargetFramework>
7+
<TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
88
</PropertyGroup>
99

1010
<ItemGroup>
@@ -13,6 +13,7 @@
1313

1414
<ItemGroup>
1515
<ProjectReference Include="..\RabbitMQ.Client\RabbitMQ.Client.csproj" />
16+
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
1617
</ItemGroup>
1718

1819
</Project>

projects/Benchmarks/Program.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
using BenchmarkDotNet.Running;
1+
using BenchmarkDotNet.Configs;
2+
using BenchmarkDotNet.Diagnosers;
3+
using BenchmarkDotNet.Environments;
4+
using BenchmarkDotNet.Exporters;
5+
using BenchmarkDotNet.Jobs;
6+
using BenchmarkDotNet.Running;
27

3-
namespace Benchmarks
8+
namespace RabbitMQ.Benchmarks
49
{
510
public static class Program
611
{
@@ -9,4 +14,15 @@ public static void Main(string[] args)
914
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
1015
}
1116
}
17+
18+
class Config : ManualConfig
19+
{
20+
public Config()
21+
{
22+
AddJob(Job.Default.WithRuntime(CoreRuntime.Core31));
23+
AddJob(Job.Default.WithRuntime(ClrRuntime.Net48));
24+
AddExporter(DefaultExporters.Markdown, DefaultExporters.Csv);
25+
AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig()), MemoryDiagnoser.Default);
26+
}
27+
}
1228
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
6+
using BenchmarkDotNet.Attributes;
7+
8+
using RabbitMQ.Client;
9+
using RabbitMQ.Client.Impl;
10+
11+
namespace RabbitMQ.Benchmarks
12+
{
13+
[Config(typeof(Config))]
14+
[BenchmarkCategory("DataTypes")]
15+
public class DataTypeSerialization
16+
{
17+
protected readonly Memory<byte> _buffer = new Memory<byte>(new byte[16384]);
18+
protected readonly AmqpTimestamp _timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeSeconds());
19+
20+
[GlobalSetup]
21+
public virtual void SetUp() { }
22+
}
23+
24+
public class DateTypeArraySerialization : DataTypeSerialization
25+
{
26+
readonly List<object> _emptyArray = new List<object>();
27+
Memory<byte> _emptyArrayBuffer;
28+
Memory<byte> _populatedArrayBuffer;
29+
List<object> _array;
30+
31+
public override void SetUp()
32+
{
33+
_array = new List<object> { "longstring", 1234, 12.34m, _timestamp };
34+
_emptyArrayBuffer = new byte[WireFormatting.GetArrayByteCount(_emptyArray)];
35+
WireFormatting.WriteArray(_emptyArrayBuffer.Span, _emptyArray);
36+
37+
_populatedArrayBuffer = new byte[WireFormatting.GetArrayByteCount(_array)];
38+
WireFormatting.WriteArray(_populatedArrayBuffer.Span, _array);
39+
}
40+
41+
[Benchmark]
42+
public IList ArrayReadEmpty() => WireFormatting.ReadArray(_emptyArrayBuffer.Span, out _);
43+
44+
[Benchmark]
45+
public IList ArrayReadPopulated() => WireFormatting.ReadArray(_populatedArrayBuffer.Span, out _);
46+
47+
[Benchmark]
48+
public int ArrayWriteEmpty() => WireFormatting.WriteArray(_buffer.Span, _emptyArray);
49+
50+
[Benchmark]
51+
public int ArrayWritePopulated() => WireFormatting.WriteArray(_buffer.Span, _array);
52+
}
53+
54+
public class DataTypeTableSerialization : DataTypeSerialization
55+
{
56+
IDictionary<string, object> _emptyDict = new Dictionary<string, object>();
57+
IDictionary<string, object> _populatedDict;
58+
Memory<byte> _emptyDictionaryBuffer;
59+
Memory<byte> _populatedDictionaryBuffer;
60+
61+
public override void SetUp()
62+
{
63+
_populatedDict = new Dictionary<string, object>
64+
{
65+
{ "string", "Hello" },
66+
{ "int", 1234 },
67+
{ "uint", 1234u },
68+
{ "decimal", 12.34m },
69+
{ "timestamp", _timestamp },
70+
{ "fieldtable", new Dictionary<string, object>(){ { "test", "test" } } },
71+
{ "fieldarray", new List<object> { "longstring", 1234, 12.34m, _timestamp } }
72+
};
73+
74+
_emptyDictionaryBuffer = new byte[WireFormatting.GetTableByteCount(_emptyDict)];
75+
WireFormatting.WriteTable(_emptyDictionaryBuffer.Span, _emptyDict);
76+
77+
_populatedDictionaryBuffer = new byte[WireFormatting.GetTableByteCount(_populatedDict)];
78+
WireFormatting.WriteTable(_populatedDictionaryBuffer.Span, _populatedDict);
79+
}
80+
81+
[Benchmark]
82+
public int TableReadEmpty() => WireFormatting.ReadDictionary(_emptyDictionaryBuffer.Span, out _);
83+
84+
[Benchmark]
85+
public int TableReadPopulated() => WireFormatting.ReadDictionary(_populatedDictionaryBuffer.Span, out _);
86+
87+
[Benchmark]
88+
public int TableWriteEmpty() => WireFormatting.WriteTable(_buffer.Span, _emptyDict);
89+
90+
[Benchmark]
91+
public int TableWritePopulated() => WireFormatting.WriteTable(_buffer.Span, _populatedDict);
92+
}
93+
94+
public class DataTypeLongStringSerialization : DataTypeSerialization
95+
{
96+
readonly string _longString = new string('X', 4096);
97+
readonly Memory<byte> _emptyLongStringBuffer = GenerateLongStringBuffer(string.Empty);
98+
readonly Memory<byte> _populatedLongStringBuffer = GenerateLongStringBuffer(new string('X', 4096));
99+
100+
[Benchmark]
101+
public int LongstrReadEmpty() => WireFormatting.ReadLongstr(_emptyLongStringBuffer.Span, out _);
102+
103+
[Benchmark]
104+
public int LongstrReadPopulated() => WireFormatting.ReadLongstr(_populatedLongStringBuffer.Span, out _);
105+
106+
[Benchmark]
107+
public int LongstrWriteEmpty() => WireFormatting.WriteLongstr(_buffer.Span, string.Empty);
108+
109+
[Benchmark]
110+
public int LongstrWritePopulated() => WireFormatting.WriteLongstr(_buffer.Span, _longString);
111+
112+
private static byte[] GenerateLongStringBuffer(string val)
113+
{
114+
byte[] _buffer = new byte[5 + Encoding.UTF8.GetByteCount(val)];
115+
WireFormatting.WriteLongstr(_buffer, val);
116+
return _buffer;
117+
}
118+
}
119+
120+
public class DataTypeShortStringSerialization : DataTypeSerialization
121+
{
122+
readonly string _shortString = new string('X', 255);
123+
readonly Memory<byte> _emptyShortStringBuffer = GenerateStringBuffer(string.Empty);
124+
readonly Memory<byte> _populatedShortStringBuffer = GenerateStringBuffer(new string('X', 255));
125+
126+
[Benchmark]
127+
public int ShortstrReadEmpty() => WireFormatting.ReadShortstr(_emptyShortStringBuffer.Span, out _);
128+
129+
[Benchmark]
130+
public int ShortstrReadPopulated() => WireFormatting.ReadShortstr(_populatedShortStringBuffer.Span, out _);
131+
132+
[Benchmark]
133+
public int ShortstrWriteEmpty() => WireFormatting.WriteShortstr(_buffer.Span, string.Empty);
134+
135+
[Benchmark]
136+
public int ShortstrWritePopulated() => WireFormatting.WriteShortstr(_buffer.Span, _shortString);
137+
138+
private static byte[] GenerateStringBuffer(string val)
139+
{
140+
byte[] _buffer = new byte[2 + Encoding.UTF8.GetByteCount(val)];
141+
WireFormatting.WriteShortstr(_buffer, val);
142+
return _buffer;
143+
}
144+
}
145+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
3+
using BenchmarkDotNet.Attributes;
4+
5+
using RabbitMQ.Client.Framing;
6+
using RabbitMQ.Client.Framing.Impl;
7+
8+
namespace RabbitMQ.Benchmarks
9+
{
10+
[Config(typeof(Config))]
11+
[BenchmarkCategory("Methods")]
12+
public class MethodSerializationBase
13+
{
14+
protected readonly Memory<byte> _buffer = new byte[1024];
15+
16+
[GlobalSetup]
17+
public virtual void SetUp() { }
18+
}
19+
20+
public class MethodBasicAck : MethodSerializationBase
21+
{
22+
private readonly BasicAck _basicAck = new BasicAck(ulong.MaxValue, true);
23+
public override void SetUp() => _basicAck.WriteArgumentsTo(_buffer.Span);
24+
25+
[Benchmark]
26+
public object BasicAckRead() => new BasicAck(_buffer.Span);
27+
28+
[Benchmark]
29+
public int BasicAckWrite() => _basicAck.WriteArgumentsTo(_buffer.Span);
30+
}
31+
32+
public class MethodBasicDeliver : MethodSerializationBase
33+
{
34+
private readonly BasicDeliver _basicDeliver = new BasicDeliver(string.Empty, 0, false, string.Empty, string.Empty);
35+
public override void SetUp() => _basicDeliver.WriteArgumentsTo(_buffer.Span);
36+
37+
[Benchmark]
38+
public object BasicDeliverRead() => new BasicDeliver(_buffer.Span);
39+
40+
[Benchmark]
41+
public int BasicDeliverWrite() => _basicDeliver.WriteArgumentsTo(_buffer.Span);
42+
}
43+
44+
public class MethodChannelClose : MethodSerializationBase
45+
{
46+
private readonly ChannelClose _channelClose = new ChannelClose(333, string.Empty, 0099, 2999);
47+
48+
public override void SetUp() => _channelClose.WriteArgumentsTo(_buffer.Span);
49+
50+
[Benchmark]
51+
public object ChannelCloseRead() => new ChannelClose(_buffer.Span);
52+
53+
[Benchmark]
54+
public int ChannelCloseWrite() => _channelClose.WriteArgumentsTo(_buffer.Span);
55+
}
56+
57+
public class MethodBasicProperties : MethodSerializationBase
58+
{
59+
private readonly BasicProperties _basicProperties = new BasicProperties { Persistent = true, AppId = "AppId", ContentEncoding = "content", };
60+
public override void SetUp() => _basicProperties.WritePropertiesTo(_buffer.Span);
61+
62+
[Benchmark]
63+
public object BasicPropertiesRead() => new BasicProperties(_buffer.Span);
64+
65+
[Benchmark]
66+
public int BasicPropertiesWrite() => _basicProperties.WritePropertiesTo(_buffer.Span);
67+
}
68+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
3+
using BenchmarkDotNet.Attributes;
4+
5+
using RabbitMQ.Client;
6+
using RabbitMQ.Client.Impl;
7+
8+
namespace RabbitMQ.Benchmarks
9+
{
10+
[Config(typeof(Config))]
11+
[BenchmarkCategory("Primitives")]
12+
public class PrimitivesBase
13+
{
14+
protected Memory<byte> _buffer = new byte[16];
15+
16+
[GlobalSetup]
17+
public virtual void Setup() { }
18+
}
19+
20+
public class PrimitivesDecimal : PrimitivesBase
21+
{
22+
public override void Setup() => WireFormatting.WriteDecimal(_buffer.Span, 123.45m);
23+
24+
[Benchmark]
25+
public decimal DecimalRead() => WireFormatting.ReadDecimal(_buffer.Span);
26+
27+
[Benchmark]
28+
public int DecimalWrite() => WireFormatting.WriteDecimal(_buffer.Span, 123.45m);
29+
}
30+
31+
public class PrimitivesLong : PrimitivesBase
32+
{
33+
public override void Setup() => WireFormatting.WriteLong(_buffer.Span, 12345u);
34+
35+
[Benchmark]
36+
public int LongRead() => WireFormatting.ReadLong(_buffer.Span, out _);
37+
38+
[Benchmark]
39+
public int LongWrite() => WireFormatting.WriteLong(_buffer.Span, 12345u);
40+
}
41+
42+
public class PrimitivesLonglong : PrimitivesBase
43+
{
44+
public override void Setup() => WireFormatting.WriteLonglong(_buffer.Span, 12345ul);
45+
46+
[Benchmark]
47+
public int LonglongRead() => WireFormatting.ReadLonglong(_buffer.Span, out _);
48+
49+
[Benchmark]
50+
public int LonglongWrite() => WireFormatting.WriteLonglong(_buffer.Span, 12345ul);
51+
}
52+
53+
public class PrimitivesShort : PrimitivesBase
54+
{
55+
public override void Setup() => WireFormatting.WriteShort(_buffer.Span, 12345);
56+
57+
[Benchmark]
58+
public int ShortRead() => WireFormatting.ReadShort(_buffer.Span, out _);
59+
60+
[Benchmark]
61+
public int ShortWrite() => WireFormatting.WriteShort(_buffer.Span, 12345);
62+
}
63+
64+
public class PrimitivesTimestamp : PrimitivesBase
65+
{
66+
AmqpTimestamp _timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeSeconds());
67+
68+
public override void Setup() => WireFormatting.WriteTimestamp(_buffer.Span, _timestamp);
69+
70+
[Benchmark]
71+
public int TimestampRead() => WireFormatting.ReadTimestamp(_buffer.Span, out _);
72+
73+
[Benchmark]
74+
public int TimestampWrite() => WireFormatting.WriteTimestamp(_buffer.Span, _timestamp);
75+
}
76+
}

projects/Benchmarks/WireFormatting/WireFormatting_Read_BasicAck.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

projects/Benchmarks/WireFormatting/WireFormatting_Read_BasicDeliver.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)