1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+
4
+ using System . Runtime . CompilerServices ;
5
+ using BenchmarkDotNet . Attributes ;
6
+ using Embedded . perftest ;
7
+ using Garnet . server ;
8
+
9
+ namespace BDN . benchmark . Resp
10
+ {
11
+ [ MemoryDiagnoser ]
12
+ public unsafe class RespAofStress
13
+ {
14
+ EmbeddedRespServer server ;
15
+ RespServerSession session ;
16
+ const int batchSize = 128 ;
17
+
18
+ static ReadOnlySpan < byte > SET => "*3\r \n $3\r \n SET\r \n $1\r \n a\r \n $1\r \n a\r \n "u8 ;
19
+ byte [ ] setRequestBuffer ;
20
+ byte * setRequestBufferPointer ;
21
+
22
+ static ReadOnlySpan < byte > INCR => "*2\r \n $4\r \n INCR\r \n $1\r \n i\r \n "u8 ;
23
+ byte [ ] incrRequestBuffer ;
24
+ byte * incrRequestBufferPointer ;
25
+
26
+ static ReadOnlySpan < byte > LPUSHPOP => "*3\r \n $5\r \n LPUSH\r \n $1\r \n d\r \n $1\r \n e\r \n *2\r \n $4\r \n LPOP\r \n $1\r \n d\r \n "u8 ;
27
+ byte [ ] lPushPopRequestBuffer ;
28
+ byte * lPushPopRequestBufferPointer ;
29
+
30
+ [ GlobalSetup ]
31
+ public void GlobalSetup ( )
32
+ {
33
+ var opt = new GarnetServerOptions
34
+ {
35
+ QuietMode = true ,
36
+ EnableAOF = true ,
37
+ UseAofNullDevice = true ,
38
+ MainMemoryReplication = true ,
39
+ CommitFrequencyMs = - 1 ,
40
+ AofPageSize = "128m" ,
41
+ AofMemorySize = "256m" ,
42
+ } ;
43
+ server = new EmbeddedRespServer ( opt ) ;
44
+
45
+ session = server . GetRespSession ( ) ;
46
+
47
+ setRequestBuffer = GC . AllocateArray < byte > ( SET . Length * batchSize , pinned : true ) ;
48
+ setRequestBufferPointer = ( byte * ) Unsafe . AsPointer ( ref setRequestBuffer [ 0 ] ) ;
49
+ for ( int i = 0 ; i < batchSize ; i ++ )
50
+ SET . CopyTo ( new Span < byte > ( setRequestBuffer ) . Slice ( i * SET . Length ) ) ;
51
+
52
+ _ = session . TryConsumeMessages ( setRequestBufferPointer , setRequestBuffer . Length ) ;
53
+
54
+ incrRequestBuffer = GC . AllocateArray < byte > ( INCR . Length * batchSize , pinned : true ) ;
55
+ incrRequestBufferPointer = ( byte * ) Unsafe . AsPointer ( ref incrRequestBuffer [ 0 ] ) ;
56
+ for ( int i = 0 ; i < batchSize ; i ++ )
57
+ INCR . CopyTo ( new Span < byte > ( incrRequestBuffer ) . Slice ( i * INCR . Length ) ) ;
58
+
59
+ _ = session . TryConsumeMessages ( incrRequestBufferPointer , incrRequestBuffer . Length ) ;
60
+
61
+ lPushPopRequestBuffer = GC . AllocateArray < byte > ( LPUSHPOP . Length * batchSize , pinned : true ) ;
62
+ lPushPopRequestBufferPointer = ( byte * ) Unsafe . AsPointer ( ref lPushPopRequestBuffer [ 0 ] ) ;
63
+ for ( int i = 0 ; i < batchSize ; i ++ )
64
+ LPUSHPOP . CopyTo ( new Span < byte > ( lPushPopRequestBuffer ) . Slice ( i * LPUSHPOP . Length ) ) ;
65
+
66
+ // Pre-populate list with a single element to avoid repeatedly emptying it during the benchmark
67
+ SlowConsumeMessage ( "*3\r \n $5\r \n LPUSH\r \n $1\r \n d\r \n $1\r \n f\r \n "u8 ) ;
68
+ }
69
+
70
+ [ GlobalCleanup ]
71
+ public void GlobalCleanup ( )
72
+ {
73
+ session . Dispose ( ) ;
74
+ server . Dispose ( ) ;
75
+ }
76
+
77
+ [ Benchmark ]
78
+ public void Set ( )
79
+ {
80
+ _ = session . TryConsumeMessages ( setRequestBufferPointer , setRequestBuffer . Length ) ;
81
+ }
82
+
83
+ [ Benchmark ]
84
+ public void Increment ( )
85
+ {
86
+ _ = session . TryConsumeMessages ( incrRequestBufferPointer , incrRequestBuffer . Length ) ;
87
+ }
88
+
89
+ [ Benchmark ]
90
+ public void LPushPop ( )
91
+ {
92
+ _ = session . TryConsumeMessages ( lPushPopRequestBufferPointer , lPushPopRequestBuffer . Length ) ;
93
+ }
94
+
95
+ private void SlowConsumeMessage ( ReadOnlySpan < byte > message )
96
+ {
97
+ var buffer = GC . AllocateArray < byte > ( message . Length , pinned : true ) ;
98
+ var bufferPointer = ( byte * ) Unsafe . AsPointer ( ref buffer [ 0 ] ) ;
99
+ message . CopyTo ( new Span < byte > ( buffer ) ) ;
100
+ _ = session . TryConsumeMessages ( bufferPointer , buffer . Length ) ;
101
+ }
102
+ }
103
+ }
0 commit comments