Skip to content

Commit d3c6c94

Browse files
authored
Merge pull request #13 from progaudi/v1.1.0
V1.1.0
2 parents 25646c2 + 4daa9b0 commit d3c6c94

File tree

16 files changed

+120
-230
lines changed

16 files changed

+120
-230
lines changed

.appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ init:
3030
environment:
3131
# this is how to set encrypted variable. Go to "Encrypt data" page in account menu to encrypt data.
3232
NUGET_API_KEY:
33-
secure: +Qor7qH6REVQKnwKWnPnTt9vMIlk3knVatE7zySAPvm+ZQdedf4GllTUYg2mmlCC
33+
secure: FAFEGEJgtKio/U/LIb4la1fOwPnFBenh58MciTjhEJgR+RbERs0sJE6mvaYF8rSv
3434

3535
# scripts that run after cloning repository
3636
install:

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM microsoft/dotnet:2.1-sdk as builder
1+
FROM microsoft/dotnet:2.1.302-sdk as builder
22

33
WORKDIR /app
44
ADD . /app
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System.Runtime.CompilerServices;
2+
using ProGaudi.MsgPack;
3+
4+
namespace msgpack.spec.linux
5+
{
6+
public static class MsgPackSpecPointer
7+
{
8+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9+
public static unsafe int WriteUInt32(byte* buffer, int idx, uint value)
10+
{
11+
if (value <= DataCodes.FixPositiveMax) return WritePositiveFixInt(buffer, idx, (byte) value);
12+
if (value <= byte.MaxValue) return WriteFixUInt8(buffer, idx, (byte) value);
13+
if (value <= ushort.MaxValue) return WriteFixUInt16(buffer, idx, (ushort) value);
14+
return WriteFixUInt32(buffer, idx, value);
15+
}
16+
17+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
18+
public static unsafe int WritePositiveFixInt(byte* buffer, int idx, byte value)
19+
{
20+
if (value > DataCodes.FixPositiveMax) return Program.ThrowWrongRangeCodeException(value, DataCodes.FixPositiveMin, DataCodes.FixPositiveMax);
21+
22+
buffer[idx] = value;
23+
return 1;
24+
}
25+
26+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
27+
public static unsafe int WriteFixUInt8(byte* buffer, int idx, byte value)
28+
{
29+
buffer[idx + 1] = value;
30+
buffer[idx] = DataCodes.UInt8;
31+
return 2;
32+
}
33+
34+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
35+
public static unsafe int WriteFixUInt16(byte* buffer, int idx, ushort value)
36+
{
37+
Unsafe.WriteUnaligned(ref buffer[idx + 1], value);
38+
buffer[idx] = DataCodes.UInt16;
39+
return 3;
40+
}
41+
42+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
43+
public static unsafe int WriteFixUInt32(byte* buffer, int idx, uint value)
44+
{
45+
Unsafe.WriteUnaligned(ref buffer[idx + 1], value);
46+
buffer[idx] = DataCodes.UInt32;
47+
return 5;
48+
}
49+
}
50+
}
Lines changed: 31 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,80 @@
11
using System;
22
using System.Buffers;
3-
using System.Buffers.Binary;
4-
using System.Runtime.CompilerServices;
53
using System.Runtime.InteropServices;
64
using BenchmarkDotNet.Attributes;
75
using ProGaudi.MsgPack;
86

97
namespace msgpack.spec.linux
108
{
119
[MemoryDiagnoser]
12-
[DisassemblyDiagnoser]
10+
[DisassemblyDiagnoser(false , true)]
1311
[Q3Column]
14-
[MarkdownExporterAttribute.GitHub]
1512
public class NativeComparison
1613
{
17-
private const ushort length = 100;
18-
private const uint baseInt = 1 << 30;
14+
private const uint length = 100;
15+
private uint baseInt = 99000;
1916
private readonly byte[] _buffer = ArrayPool<byte>.Shared.Rent(short.MaxValue);
2017

21-
[Benchmark]
22-
public int MsgPackSpecArray()
23-
{
24-
var buffer = _buffer.AsSpan();
25-
var wroteSize = MsgPackSpec.WriteArray16Header(buffer, length);
26-
for (var i = 0u; i < length; i++)
27-
wroteSize += MsgPackSpec.WriteUInt32(buffer.Slice(wroteSize), baseInt);
28-
29-
return wroteSize;
30-
}
31-
[Benchmark]
32-
public int MsgPackSpecArrayMinus()
18+
[Benchmark(Baseline = true)]
19+
public int Span()
3320
{
3421
var buffer = _buffer.AsSpan();
35-
var wroteSize = MsgPackSpec.WriteArray16Header(buffer, length);
36-
for (var i = 0u; i < length; i++)
37-
wroteSize += MsgPackSpec.WriteUInt32(buffer.Slice(wroteSize), baseInt - i);
38-
39-
return wroteSize;
40-
}
41-
42-
[Benchmark]
43-
public unsafe void Pointer()
44-
{
45-
fixed (byte* pointer = &_buffer[0])
22+
var i = 0;
23+
for (; i < length; i++)
4624
{
47-
pointer[0] = DataCodes.Array16;
48-
Unsafe.WriteUnaligned(ref pointer[1], length);
49-
for (var i = 0u; i < length; i++)
50-
{
51-
pointer[3 + 5 * i] = DataCodes.UInt32;
52-
Unsafe.WriteUnaligned(ref pointer[3 + 5 * i + 1], baseInt);
53-
}
25+
baseInt -= 1000u;
26+
MsgPackSpec.WriteUInt32(buffer.Slice(5 * i), baseInt);
5427
}
28+
29+
return i;
5530
}
5631

5732
[Benchmark]
58-
public unsafe void PointerMinus()
33+
public int SpanConst()
5934
{
60-
fixed (byte* pointer = &_buffer[0])
35+
var buffer = _buffer.AsSpan();
36+
var i = 0;
37+
for (; i < length; i++)
6138
{
62-
pointer[0] = DataCodes.Array16;
63-
Unsafe.WriteUnaligned(ref pointer[1], length);
64-
for (var i = 0u; i < length; i++)
65-
{
66-
pointer[3 + 5 * i] = DataCodes.UInt32;
67-
Unsafe.WriteUnaligned(ref pointer[3 + 5 * i + 1], baseInt - i);
68-
}
39+
baseInt -= 1000u;
40+
MsgPackSpec.WriteUInt32(buffer.Slice(5 * i), length);
6941
}
70-
}
7142

72-
[Benchmark(Baseline = true)]
73-
public void CArray() => CNative.SerializeArray();
74-
75-
[Benchmark]
76-
public void CArrayMinus() => CNative.SerializeArrayMinus();
77-
78-
[Benchmark]
79-
public void CppArray() => CppNative.SerializeArray();
80-
81-
[Benchmark]
82-
public void CppArrayMinus() => CppNative.SerializeArrayMinus();
43+
return i;
44+
}
8345

8446
[Benchmark]
85-
public unsafe void PointerBigEndian()
47+
public unsafe int Fixed()
8648
{
8749
fixed (byte* pointer = &_buffer[0])
8850
{
89-
pointer[0] = DataCodes.Array16;
90-
Unsafe.WriteUnaligned(ref pointer[1], BinaryPrimitives.ReverseEndianness(length));
91-
for (var i = 0u; i < length; i++)
51+
var i = 0;
52+
for (; i < length; i++)
9253
{
93-
pointer[3 + 5 * i] = DataCodes.UInt32;
94-
Unsafe.WriteUnaligned(ref pointer[3 + 5 * i + 1], BinaryPrimitives.ReverseEndianness(baseInt));
54+
baseInt -= 1000;
55+
MsgPackSpecPointer.WriteUInt32(pointer, 5 * i, baseInt);
9556
}
96-
}
97-
}
9857

99-
[Benchmark]
100-
public void SpanBigEndian()
101-
{
102-
var pointer = _buffer.AsSpan();
103-
var l = BinaryPrimitives.ReverseEndianness(length);
104-
pointer[0] = DataCodes.Array16;
105-
MemoryMarshal.Write(pointer.Slice(1), ref l);
106-
var x = BinaryPrimitives.ReverseEndianness(baseInt);
107-
for (var i = 0; i < length; i++)
108-
{
109-
pointer[3 + 5 * i] = DataCodes.UInt32;
110-
MemoryMarshal.Write(pointer.Slice(3 + 5 * i + 1), ref x);
58+
return i;
11159
}
11260
}
11361

11462
[Benchmark]
115-
public void SpanLengthBigEndian()
116-
{
117-
var pointer = _buffer.AsSpan();
118-
var l = BinaryPrimitives.ReverseEndianness(length);
119-
pointer[0] = DataCodes.Array16;
120-
MemoryMarshal.Write(pointer.Slice(1, 2), ref l);
121-
var x = BinaryPrimitives.ReverseEndianness(baseInt);
122-
for (var i = 0; i < length; i++)
123-
{
124-
pointer[3 + 5 * i] = DataCodes.UInt32;
125-
MemoryMarshal.Write(pointer.Slice(3 + 5 * i + 1, 4), ref x);
126-
}
127-
}
63+
public uint C() => CNative.SerializeInts(length);
12864

12965
[Benchmark]
130-
public void SpanBigEndianBinaryPrimitive()
131-
{
132-
var pointer = _buffer.AsSpan();
133-
pointer[0] = DataCodes.Array16;
134-
BinaryPrimitives.WriteUInt16BigEndian(pointer.Slice(1), length);
135-
for (var i = 0; i < length; i++)
136-
{
137-
pointer[3 + 5 * i] = DataCodes.UInt32;
138-
BinaryPrimitives.WriteUInt32BigEndian(pointer.Slice(3 + 5 * i + 1), baseInt);
139-
}
140-
}
141-
142-
[Benchmark]
143-
public void Empty() => CNative.Empty();
66+
public uint Cpp() => CppNative.SerializeInts(length);
14467

14568
private static class CNative
14669
{
147-
[DllImport("libcMsgPack.so", EntryPoint = "serializeIntArray", CallingConvention = CallingConvention.Cdecl)]
148-
public static extern void SerializeArray();
149-
150-
[DllImport("libcMsgPack.so", EntryPoint = "serializeIntArrayMinus", CallingConvention = CallingConvention.Cdecl)]
151-
public static extern void SerializeArrayMinus();
152-
153-
[DllImport("libcMsgPack.so", EntryPoint = "empty", CallingConvention = CallingConvention.Cdecl)]
154-
public static extern void Empty();
70+
[DllImport("libcMsgPack.so", EntryPoint = "serializeInts", CallingConvention = CallingConvention.Cdecl)]
71+
public static extern uint SerializeInts(uint size);
15572
}
15673

15774
private static class CppNative
15875
{
159-
[DllImport("libcppMsgPack.so", EntryPoint = "serializeIntArray", CallingConvention = CallingConvention.Cdecl)]
160-
public static extern void SerializeArray();
161-
162-
[DllImport("libcMsgPack.so", EntryPoint = "serializeIntArrayMinus", CallingConvention = CallingConvention.Cdecl)]
163-
public static extern void SerializeArrayMinus();
76+
[DllImport("libcMsgPack.so", EntryPoint = "serializeInts", CallingConvention = CallingConvention.Cdecl)]
77+
public static extern uint SerializeInts(uint size);
16478
}
16579
}
16680
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
using System;
12
using BenchmarkDotNet.Running;
23

34
namespace msgpack.spec.linux
45
{
56
public static class Program
67
{
7-
private static void Main(string[] args) => BenchmarkRunner.Run<NativeComparison>();
8+
public static void Main(string[] args) => BenchmarkRunner.Run<NativeComparison>();
9+
10+
public static byte ThrowWrongRangeCodeException(byte code, byte min, byte max) => throw new InvalidOperationException(
11+
$"Wrong data code: 0x{code:x2}. Expected: 0x{min:x2} <= code <= 0x{max:x2}."
12+
);
813
}
914
}
Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,18 @@
1-
#include <msgpuck.h>
1+
#include <msgpuck.h>
22

33
char buf[65535];
44

5-
extern void serializeIntArray()
5+
extern uint32_t serializeInts(uint32_t size)
66
{
7-
const uint32_t size = 100;
8-
const int64_t base = 1L << 30;
7+
uint32_t base = 99000;
98
char *w = buf;
109

11-
w = mp_encode_array(w, size);
12-
int64_t idx = 0;
10+
uint32_t idx = 0;
1311
for (; idx < size; ++idx)
12+
{
13+
base -= 1000;
1414
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;
15+
}
2216

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-
{
17+
return idx;
3118
}

benchmarks/msgpack.spec.linux/c/cppMsgPack.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,19 @@
22

33
using namespace msgpack;
44

5-
extern "C" void serializeIntArray()
5+
extern "C" uint32_t serializeInts(uint32_t size)
66
{
7-
const uint32_t size = 100;
8-
const int64_t base = 1L << 30;
7+
uint32_t base = 99000;
98
sbuffer buffer;
109
packer<sbuffer> pk(&buffer);
1110

12-
pk.pack_array(size);
11+
uint32_t idx = 0;
1312

14-
int64_t idx = 0;
1513
for (; idx < size; ++idx)
14+
{
15+
base -= 1000;
1616
pk.pack(base);
17-
}
17+
}
1818

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);
19+
return idx;
3120
}

0 commit comments

Comments
 (0)