Skip to content

Commit aedc5e4

Browse files
authored
Merge pull request #12 from progaudi/feature/benchmark
Add a benchmark for msgpack array write.
2 parents 267b2e9 + 60c65ce commit aedc5e4

32 files changed

+357
-115
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
.git
55
*.user
66
**/*.user
7+
Dockerfile
8+
Dockerfile.*

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ FROM microsoft/dotnet:2.1-sdk as builder
33
WORKDIR /app
44
ADD . /app
55

6-
RUN IsDocker=defined dotnet build -c Release
6+
RUN IsDocker=defined dotnet build -c Release msgpack.spec.sln
77

88
RUN cat ./scripts/.travis.sdk2.txt | xargs -I {} dotnet test -c Release -f {} --no-build ./tests/msgpack.spec.tests/msgpack.spec.tests.csproj -- -parallel assemblies
99

@@ -13,6 +13,6 @@ WORKDIR /app
1313

1414
COPY --from=builder /app .
1515

16-
RUN dotnet restore
16+
RUN dotnet restore msgpack.spec.sln
1717

1818
RUN cat ./scripts/.travis.sdk1.txt | xargs -I {} dotnet test -c Release -f {} --no-build ./tests/msgpack.spec.tests/msgpack.spec.tests.csproj -- -parallel assemblies

Dockerfile.benchmark

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
FROM microsoft/dotnet:2.1-sdk
2+
3+
RUN echo "deb http://ftp.debian.org/debian stretch-backports main" | tee /etc/apt/sources.list.d/stretch-backports.list
4+
5+
RUN apt-get update \
6+
&& apt-get install -y --no-install-recommends build-essential
7+
8+
RUN apt-get -t stretch-backports install -y --no-install-recommends cmake
9+
10+
RUN mkdir -p /tmp \
11+
&& cd /tmp \
12+
&& git clone https://github.com/rtsisyk/msgpuck.git \
13+
&& cd msgpuck \
14+
&& cmake -DCMAKE_BUILD_TYPE=Release . \
15+
&& make \
16+
&& make install \
17+
&& rm -rf /tmp/msgpuck
18+
19+
RUN mkdir -p /tmp \
20+
&& cd /tmp \
21+
&& git clone https://github.com/msgpack/msgpack-c.git \
22+
&& cd msgpack-c \
23+
&& cmake -DCMAKE_BUILD_TYPE=Release . \
24+
&& make \
25+
&& make install \
26+
&& rm -rf /tmp/msgpack-c
27+
28+
WORKDIR /app
29+
RUN mkdir -p src/msgpack.spec tests/msgpack.spec.tests benchmarks/msgpack.spec.linux
30+
31+
ADD msgpack.spec.sln /app
32+
ADD src/msgpack.spec/msgpack.spec.csproj /app/src/msgpack.spec/
33+
ADD tests/msgpack.spec.tests/msgpack.spec.tests.csproj /app/tests/msgpack.spec.tests/
34+
ADD benchmarks/msgpack.spec.linux/msgpack.spec.linux.csproj /app/benchmarks/msgpack.spec.linux/
35+
36+
RUN IsDocker=defined dotnet restore
37+
38+
ADD . /app
39+
40+
RUN IsDocker=defined dotnet build --no-restore -c Release
41+
42+
RUN (cd /app/benchmarks/msgpack.spec.linux/c \
43+
&& cmake -DCMAKE_BUILD_TYPE=Release . \
44+
&& make \
45+
&& make install)
46+
47+
CMD ["dotnet", "/app/benchmarks/msgpack.spec.linux/bin/Release/netcoreapp2.1/msgpack.spec.linux.dll"]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Buffers;
3+
using BenchmarkDotNet.Attributes;
4+
using ProGaudi.MsgPack;
5+
6+
namespace msgpack.spec.linux
7+
{
8+
[MemoryDiagnoser]
9+
[DisassemblyDiagnoser]
10+
[Q3Column]
11+
[MarkdownExporterAttribute.GitHub]
12+
public class NativeComparison
13+
{
14+
private const ushort length = 100;
15+
private const uint baseInt = 1 << 30;
16+
private readonly byte[] _buffer = ArrayPool<byte>.Shared.Rent(short.MaxValue);
17+
18+
[Benchmark]
19+
public int MsgPackSpecArray()
20+
{
21+
var buffer = _buffer.AsSpan();
22+
var wroteSize = MsgPackSpec.WriteArray16Header(buffer, length);
23+
for (var i = 0u; i < length; i++)
24+
wroteSize += MsgPackSpec.WriteUInt32(buffer.Slice(wroteSize), baseInt);
25+
26+
return wroteSize;
27+
}
28+
29+
[Benchmark]
30+
public int MsgPackSpecArrayMinus()
31+
{
32+
var buffer = _buffer.AsSpan();
33+
var wroteSize = MsgPackSpec.WriteArray16Header(buffer, length);
34+
for (var i = 0u; i < length; i++)
35+
wroteSize += MsgPackSpec.WriteUInt32(buffer.Slice(wroteSize), baseInt - i);
36+
37+
return wroteSize;
38+
}
39+
}
40+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using BenchmarkDotNet.Running;
2+
3+
namespace msgpack.spec.linux
4+
{
5+
public static class Program
6+
{
7+
private static void Main(string[] args) => BenchmarkRunner.Run<NativeComparison>();
8+
}
9+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# CMakeList.txt : CMake project for TestCMake, include source and define
2+
# project specific logic here.
3+
#
4+
cmake_minimum_required (VERSION 3.8)
5+
SET(CMAKE_CXX_FLAGS "-O2")
6+
SET(CMAKE_C_FLAGS "-O2")
7+
8+
project ("cMsgPack")
9+
10+
# Taken here: https://github.com/tarantool/tarantool/blob/2.0/cmake/FindMsgPuck.cmake
11+
# - Find libmsgpuck header-only library
12+
find_path(MSGPUCK_INCLUDE_DIR msgpuck.h PATH_SUFFIXES msgpuck)
13+
find_library(MSGPUCK_LIBRARY NAMES libmsgpuck.a)
14+
15+
include(FindPackageHandleStandardArgs)
16+
find_package_handle_standard_args(MsgPuck REQUIRED_VARS MSGPUCK_INCLUDE_DIR MSGPUCK_LIBRARY)
17+
set(MSGPUCK_INCLUDE_DIRS ${MSGPUCK_INCLUDE_DIR})
18+
set(MSGPUCK_LIBRARIES ${MSGPUCK_LIBRARY})
19+
mark_as_advanced(MSGPUCK_INCLUDE_DIR MSGPUCK_INCLUDE_DIRS
20+
MSGPUCK_LIBRARY MSGPUCK_LIBRARIES)
21+
22+
include_directories(MSGPUCK_INCLUDE_DIR)
23+
24+
add_library(cMsgPack SHARED "cMsgPack.c")
25+
add_library(cppMsgPack SHARED "cppMsgPack.cpp")
26+
27+
target_link_libraries(cMsgPack ${MSGPUCK_LIBRARIES})
28+
install(TARGETS cMsgPack LIBRARY DESTINATION /lib)
29+
install(TARGETS cppMsgPack LIBRARY DESTINATION /lib)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <msgpuck.h>
2+
3+
char buf[65535];
4+
5+
extern void serializeIntArray()
6+
{
7+
const uint32_t size = 100;
8+
const int64_t base = 1L << 30;
9+
char *w = buf;
10+
11+
w = mp_encode_array(w, size);
12+
int64_t idx = 0;
13+
for (; idx < size; ++idx)
14+
w = mp_encode_uint(w, base);
15+
}
16+
17+
extern void serializeIntArrayMinus()
18+
{
19+
const uint32_t size = 100;
20+
const int64_t base = 1L << 30;
21+
char *w = buf;
22+
23+
w = mp_encode_array(w, size);
24+
int64_t idx = 0;
25+
for (; idx < size; ++idx)
26+
w = mp_encode_uint(w, base-idx);
27+
}
28+
29+
extern void empty()
30+
{
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <msgpack.hpp>
2+
3+
using namespace msgpack;
4+
5+
extern "C" void serializeIntArray()
6+
{
7+
const uint32_t size = 100;
8+
const int64_t base = 1L << 30;
9+
sbuffer buffer;
10+
packer<sbuffer> pk(&buffer);
11+
12+
pk.pack_array(size);
13+
14+
int64_t idx = 0;
15+
for (; idx < size; ++idx)
16+
pk.pack(base);
17+
}
18+
19+
extern "C" void serializeIntArrayMinus()
20+
{
21+
const uint32_t size = 100;
22+
const int64_t base = 1L << 30;
23+
sbuffer buffer;
24+
packer<sbuffer> pk(&buffer);
25+
26+
pk.pack_array(size);
27+
28+
int64_t idx = 0;
29+
for (; idx < size; ++idx)
30+
pk.pack(base-idx);
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.1</TargetFramework>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<PackageReference Include="BenchmarkDotNet" Version="0.11.0" />
10+
<PackageReference Include="MessagePack" Version="1.7.3.4" />
11+
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
12+
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.1" />
13+
</ItemGroup>
14+
<ItemGroup>
15+
<ProjectReference Include="..\..\src\msgpack.spec\msgpack.spec.csproj" />
16+
</ItemGroup>
17+
</Project>

msgpack.spec.sln

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio 15
43
VisualStudioVersion = 15.0.27703.2035
@@ -11,6 +10,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "msgpack.spec.tests", "tests
1110
EndProject
1211
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "msgpack.spec", "src\msgpack.spec\msgpack.spec.csproj", "{7058F131-95D8-411F-A8F9-5D545B2F6CD6}"
1312
EndProject
13+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{32293110-6ADF-4327-A607-007178B3FF4F}"
14+
EndProject
15+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "msgpack.spec.linux", "benchmarks\msgpack.spec.linux\msgpack.spec.linux.csproj", "{768BD4CC-7D1F-4861-A22B-ED61F624BFD0}"
16+
EndProject
1417
Global
1518
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1619
Debug|Any CPU = Debug|Any CPU
@@ -25,13 +28,18 @@ Global
2528
{7058F131-95D8-411F-A8F9-5D545B2F6CD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
2629
{7058F131-95D8-411F-A8F9-5D545B2F6CD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
2730
{7058F131-95D8-411F-A8F9-5D545B2F6CD6}.Release|Any CPU.Build.0 = Release|Any CPU
31+
{768BD4CC-7D1F-4861-A22B-ED61F624BFD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32+
{768BD4CC-7D1F-4861-A22B-ED61F624BFD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
33+
{768BD4CC-7D1F-4861-A22B-ED61F624BFD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
34+
{768BD4CC-7D1F-4861-A22B-ED61F624BFD0}.Release|Any CPU.Build.0 = Release|Any CPU
2835
EndGlobalSection
2936
GlobalSection(SolutionProperties) = preSolution
3037
HideSolutionNode = FALSE
3138
EndGlobalSection
3239
GlobalSection(NestedProjects) = preSolution
3340
{5E849934-F19E-4BAA-9AD5-27AE3FED2C9C} = {CE0D00AA-B446-4986-B5A8-9C5F770A1B9F}
3441
{7058F131-95D8-411F-A8F9-5D545B2F6CD6} = {3BE86A5A-FF70-47D4-B236-5DCDEAC91BDF}
42+
{768BD4CC-7D1F-4861-A22B-ED61F624BFD0} = {32293110-6ADF-4327-A607-007178B3FF4F}
3543
EndGlobalSection
3644
GlobalSection(ExtensibilityGlobals) = postSolution
3745
SolutionGuid = {86BE877E-C4AB-4B18-9676-56B093AE448B}

src/msgpack.spec/MsgPackSpec.Array.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public static byte ReadFixArrayHeader(ReadOnlySpan<byte> buffer, out int readSiz
123123
if (FixArrayMin <= buffer[0] && buffer[0] <= FixArrayMax)
124124
return (byte) (buffer[0] - FixArrayMin);
125125

126-
throw WrongRangeCodeException(buffer[0], FixArrayMin, FixArrayMax);
126+
return ThrowWrongRangeCodeException(buffer[0], FixArrayMin, FixArrayMax);
127127
}
128128

129129
/// <summary>
@@ -162,7 +162,7 @@ public static ushort ReadArray16Header(ReadOnlySpan<byte> buffer, out int readSi
162162
readSize = 3;
163163
if (buffer[0] == Array16)
164164
return BinaryPrimitives.ReadUInt16BigEndian(buffer.Slice(1));
165-
throw WrongCodeException(buffer[0], Array16);
165+
return ThrowWrongCodeException(buffer[0], Array16);
166166
}
167167

168168
/// <summary>
@@ -198,7 +198,7 @@ public static uint ReadArray32Header(ReadOnlySpan<byte> buffer, out int readSize
198198
readSize = 5;
199199
if (buffer[0] == Array32)
200200
return BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(1));
201-
throw WrongCodeException(buffer[0], Array32);
201+
return ThrowWrongCodeException(buffer[0], Array32);
202202
}
203203

204204
/// <summary>
@@ -233,7 +233,7 @@ public static int WriteArrayHeader(Span<byte> buffer, int length)
233233
{
234234
if (length < 0)
235235
{
236-
throw LengthShouldBeNonNegative(length);
236+
return ThrowLengthShouldBeNonNegative(length);
237237
}
238238

239239
if (length <= FixArrayMaxLength)
@@ -306,10 +306,11 @@ public static int ReadArrayHeader(ReadOnlySpan<byte> buffer, out int readSize)
306306
return (int) uint32Value;
307307
}
308308

309-
throw DataIsTooLarge(uint32Value);
309+
return ThrowDataIsTooLarge(uint32Value);
310310
}
311311

312-
throw WrongArrayHeader(buffer[0]);
312+
readSize = 0;
313+
return ThrowWrongArrayHeader(buffer[0]);
313314
}
314315

315316
/// <summary>

src/msgpack.spec/MsgPackSpec.Binary.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public static byte ReadBinary8Header(ReadOnlySpan<byte> buffer, out int readSize
117117
if (buffer[0] == DataCodes.Binary8)
118118
return buffer[1];
119119

120-
throw WrongCodeException(buffer[0], DataCodes.Binary8);
120+
return ThrowWrongCodeException(buffer[0], DataCodes.Binary8);
121121
}
122122

123123
/// <summary>
@@ -155,7 +155,7 @@ public static ushort ReadBinary16Header(ReadOnlySpan<byte> buffer, out int readS
155155
if (buffer[0] == DataCodes.Binary16)
156156
return BinaryPrimitives.ReadUInt16BigEndian(buffer.Slice(1));
157157

158-
throw WrongCodeException(buffer[0], DataCodes.Binary16);
158+
return ThrowWrongCodeException(buffer[0], DataCodes.Binary16);
159159
}
160160

161161
/// <summary>
@@ -193,7 +193,7 @@ public static uint ReadBinary32Header(ReadOnlySpan<byte> buffer, out int readSiz
193193
if (buffer[0] == DataCodes.Binary32)
194194
return BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(1));
195195

196-
throw WrongCodeException(buffer[0], DataCodes.Binary32);
196+
return ThrowWrongCodeException(buffer[0], DataCodes.Binary32);
197197
}
198198

199199
/// <summary>
@@ -229,7 +229,7 @@ public static int WriteBinaryHeader(Span<byte> buffer, int length)
229229
{
230230
if (length < 0)
231231
{
232-
throw LengthShouldBeNonNegative(length);
232+
return ThrowLengthShouldBeNonNegative(length);
233233
}
234234

235235
if (length <= byte.MaxValue)
@@ -296,9 +296,10 @@ public static int ReadBinaryHeader(ReadOnlySpan<byte> buffer, out int readSize)
296296
return (int) uint32Value;
297297
}
298298

299-
throw DataIsTooLarge(uint32Value);
299+
return ThrowDataIsTooLarge(uint32Value);
300300
default:
301-
throw WrongCodeException(buffer[0], DataCodes.Binary8, DataCodes.Binary16, DataCodes.Binary32);
301+
readSize = 0;
302+
return ThrowWrongCodeException(buffer[0], DataCodes.Binary8, DataCodes.Binary16, DataCodes.Binary32);
302303
}
303304
}
304305

@@ -346,7 +347,7 @@ public static int WriteBinary8(Span<byte> buffer, ReadOnlySpan<byte> binary)
346347
var length = binary.Length;
347348
if (length > byte.MaxValue)
348349
{
349-
throw DataIsTooLarge(binary.Length, byte.MaxValue, nameof(DataCodes.Binary8), DataCodes.Binary8);
350+
return ThrowDataIsTooLarge(binary.Length, byte.MaxValue, nameof(DataCodes.Binary8), DataCodes.Binary8);
350351
}
351352

352353
var result = WriteBinary8Header(buffer, (byte)length);
@@ -395,7 +396,7 @@ public static int WriteBinary16(Span<byte> buffer, ReadOnlySpan<byte> binary)
395396
var length = binary.Length;
396397
if (length > ushort.MaxValue)
397398
{
398-
throw DataIsTooLarge(binary.Length, ushort.MaxValue, nameof(DataCodes.Binary16), DataCodes.Binary16);
399+
return ThrowDataIsTooLarge(binary.Length, ushort.MaxValue, nameof(DataCodes.Binary16), DataCodes.Binary16);
399400
}
400401

401402
var result = WriteBinary16Header(buffer, (ushort) length);
@@ -574,7 +575,7 @@ public static bool TryReadBinary16(ReadOnlySpan<byte> buffer, out IMemoryOwner<b
574575
public static IMemoryOwner<byte> ReadBinary32(ReadOnlySpan<byte> buffer, out int readSize)
575576
{
576577
var length = ReadBinary32Header(buffer, out readSize);
577-
if (length > int.MaxValue) throw DataIsTooLarge(length);
578+
if (length > int.MaxValue) ThrowDataIsTooLarge(length);
578579
var resultLength = (int)length;
579580
return ReadBinaryBlob(buffer, ref readSize, resultLength);
580581
}

0 commit comments

Comments
 (0)