diff --git a/benchmark/BDN.benchmark/BDN.benchmark.csproj b/benchmark/BDN.benchmark/BDN.benchmark.csproj index 2965fbcf83..21d1589cc3 100644 --- a/benchmark/BDN.benchmark/BDN.benchmark.csproj +++ b/benchmark/BDN.benchmark/BDN.benchmark.csproj @@ -22,9 +22,10 @@ - - - - + + + + + diff --git a/benchmark/BDN.benchmark/Cluster/ClusterContext.cs b/benchmark/BDN.benchmark/Cluster/ClusterContext.cs index 4215e0da68..1ae7fc4540 100644 --- a/benchmark/BDN.benchmark/Cluster/ClusterContext.cs +++ b/benchmark/BDN.benchmark/Cluster/ClusterContext.cs @@ -20,7 +20,7 @@ unsafe class ClusterContext public static ReadOnlySpan keyTag => "{0}"u8; public Request[] singleGetSet; public Request[] singleMGetMSet; - public Request singleCPBSET; + public Request singleCTXNSET; public void Dispose() { @@ -41,7 +41,7 @@ public void SetupSingleInstance(bool disableSlotVerification = false) opt.CheckpointDir = "/tmp"; server = new EmbeddedRespServer(opt); session = server.GetRespSession(); - _ = server.Register.NewTransactionProc(CustomProcSet.CommandName, () => new CustomProcSet(), new RespCommandsInfo { Arity = CustomProcSet.Arity }); + _ = server.Register.NewTransactionProc(CustomTxnSet.CommandName, () => new CustomTxnSet(), new RespCommandsInfo { Arity = CustomTxnSet.Arity }); } public void AddSlotRange(List<(int, int)> slotRanges) @@ -134,7 +134,7 @@ public void CreateMGetMSet(int keySize = 8, int valueSize = 32, int batchSize = singleMGetMSet = [mGetReq, mSetReq]; } - public void CreateCPBSET(int keySize = 8, int batchSize = 100) + public void CreateCTXNSET(int keySize = 8, int batchSize = 100) { var keys = new byte[8][]; for (var i = 0; i < 8; i++) @@ -145,22 +145,22 @@ public void CreateCPBSET(int keySize = 8, int batchSize = 100) benchUtils.RandomBytes(ref keys[i], startOffset: keyTag.Length); } - var cpbsetByteCount = "*9\r\n$6\r\nCPBSET\r\n"u8.Length + (8 * (1 + NumUtils.NumDigits(keySize) + 2 + keySize + 2)); - var cpbsetReq = new Request(batchSize * cpbsetByteCount); - var curr = cpbsetReq.ptr; - var end = curr + cpbsetReq.buffer.Length; + var ctxnsetByteCount = "*9\r\n$7\r\nCTXNSET\r\n"u8.Length + (8 * (1 + NumUtils.NumDigits(keySize) + 2 + keySize + 2)); + var ctxnsetReq = new Request(batchSize * ctxnsetByteCount); + var curr = ctxnsetReq.ptr; + var end = curr + ctxnsetReq.buffer.Length; for (var i = 0; i < batchSize; i++) { _ = RespWriteUtils.WriteArrayLength(9, ref curr, end); - _ = RespWriteUtils.WriteBulkString("CPBSET"u8, ref curr, end); + _ = RespWriteUtils.WriteBulkString("CTXNSET"u8, ref curr, end); for (var j = 0; j < 8; j++) { _ = RespWriteUtils.WriteBulkString(keys[j], ref curr, end); } } - singleCPBSET = cpbsetReq; + singleCTXNSET = ctxnsetReq; } public void Consume(byte* ptr, int length) diff --git a/benchmark/BDN.benchmark/Cluster/ClusterOperations.cs b/benchmark/BDN.benchmark/Cluster/ClusterOperations.cs index 3602060a12..2799885ae9 100644 --- a/benchmark/BDN.benchmark/Cluster/ClusterOperations.cs +++ b/benchmark/BDN.benchmark/Cluster/ClusterOperations.cs @@ -36,14 +36,14 @@ public virtual void GlobalSetup() cc.AddSlotRange([(0, 16383)]); cc.CreateGetSet(); cc.CreateMGetMSet(); - cc.CreateCPBSET(); + cc.CreateCTXNSET(); // Warmup/Prepopulate stage cc.Consume(cc.singleGetSet[1].ptr, cc.singleGetSet[1].buffer.Length); // Warmup/Prepopulate stage cc.Consume(cc.singleMGetMSet[1].ptr, cc.singleMGetMSet[1].buffer.Length); // Warmup/Prepopulate stage - cc.Consume(cc.singleCPBSET.ptr, cc.singleCPBSET.buffer.Length); + cc.Consume(cc.singleCTXNSET.ptr, cc.singleCTXNSET.buffer.Length); } [GlobalCleanup] @@ -77,9 +77,9 @@ public void MSet() } [Benchmark] - public void CPBSET() + public void CTXNSET() { - cc.Consume(cc.singleCPBSET.ptr, cc.singleCPBSET.buffer.Length); + cc.Consume(cc.singleCTXNSET.ptr, cc.singleCTXNSET.buffer.Length); } } } \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Custom/CustomProcSet.cs b/benchmark/BDN.benchmark/Custom/CustomProcSet.cs new file mode 100644 index 0000000000..7e2b482a96 --- /dev/null +++ b/benchmark/BDN.benchmark/Custom/CustomProcSet.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using Garnet.common; +using Garnet.server; + +namespace BDN.benchmark.CustomProcs +{ + class CustomProcSet : CustomProcedure + { + /// + /// Parameters including command + /// + public const int Arity = 9; + + /// + /// Command name + /// + public const string CommandName = "CPROCSET"; + + /// + /// CPROCSET key1 key2 key3 key4 value1 value2 value3 value4 + /// + /// + /// + /// + /// + /// + public override bool Execute(TGarnetApi api, ref CustomProcedureInput procInput, ref MemoryResult output) + { + var offset = 0; + var setA = GetNextArg(ref procInput, ref offset); + var setB = GetNextArg(ref procInput, ref offset); + var setC = GetNextArg(ref procInput, ref offset); + var setD = GetNextArg(ref procInput, ref offset); + + var valueA = GetNextArg(ref procInput, ref offset); + var valueB = GetNextArg(ref procInput, ref offset); + var valueC = GetNextArg(ref procInput, ref offset); + var valueD = GetNextArg(ref procInput, ref offset); + + _ = api.SET(setA, valueA); + _ = api.SET(setB, valueB); + _ = api.SET(setC, valueC); + _ = api.SET(setD, valueD); + + return true; + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/CustomProcs/CustomProcSet.cs b/benchmark/BDN.benchmark/Custom/CustomTxnSet.cs similarity index 90% rename from benchmark/BDN.benchmark/CustomProcs/CustomProcSet.cs rename to benchmark/BDN.benchmark/Custom/CustomTxnSet.cs index d602f0d6c4..b833e696c5 100644 --- a/benchmark/BDN.benchmark/CustomProcs/CustomProcSet.cs +++ b/benchmark/BDN.benchmark/Custom/CustomTxnSet.cs @@ -8,9 +8,9 @@ namespace BDN.benchmark.CustomProcs { /// - /// Custom procedure to set values + /// Custom transaction to set values /// - sealed class CustomProcSet : CustomTransactionProcedure + sealed class CustomTxnSet : CustomTransactionProcedure { /// /// Parameters including command @@ -20,7 +20,7 @@ sealed class CustomProcSet : CustomTransactionProcedure /// /// Command name /// - public const string CommandName = "CPBSET"; + public const string CommandName = "CTXNSET"; ArgSlice setA; ArgSlice setB; @@ -33,7 +33,7 @@ sealed class CustomProcSet : CustomTransactionProcedure ArgSlice valueD; /// - /// CPBSET key1 key2 key3 key4 value1 value2 value3 value4 + /// CTXNSET key1 key2 key3 key4 value1 value2 value3 value4 /// /// /// diff --git a/benchmark/BDN.benchmark/Operations/CustomOperations.cs b/benchmark/BDN.benchmark/Operations/CustomOperations.cs new file mode 100644 index 0000000000..eea46648c2 --- /dev/null +++ b/benchmark/BDN.benchmark/Operations/CustomOperations.cs @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using BDN.benchmark.CustomProcs; +using BenchmarkDotNet.Attributes; +using Garnet; +using Garnet.server; + +namespace BDN.benchmark.Operations +{ + /// + /// Benchmark for ObjectOperations + /// + [MemoryDiagnoser] + public unsafe class CustomOperations : OperationsBase + { + static ReadOnlySpan SETIFPM => "*4\r\n$7\r\nSETIFPM\r\n$1\r\nk\r\n$3\r\nval\r\n$1\r\nv\r\n"u8; + byte[] setIfPmRequestBuffer; + byte* setIfPmRequestBufferPointer; + + static ReadOnlySpan MYDICTSETGET => "*4\r\n$9\r\nMYDICTSET\r\n$2\r\nck\r\n$1\r\nf\r\n$1\r\nv\r\n*3\r\n$9\r\nMYDICTGET\r\n$2\r\nck\r\n$1\r\nf\r\n"u8; + byte[] myDictSetGetRequestBuffer; + byte* myDictSetGetRequestBufferPointer; + + static ReadOnlySpan CTXNSET => "*9\r\n$7\r\nCTXNSET\r\n$6\r\n{0}000\r\n$6\r\n{0}001\r\n$6\r\n{0}002\r\n$6\r\n{0}003\r\n$6\r\n{0}000\r\n$6\r\n{0}001\r\n$6\r\n{0}002\r\n$6\r\n{0}003\r\n"u8; + byte[] ctxnsetBuffer; + byte* ctxnsetBufferPointer; + + static ReadOnlySpan CPROCSET => "*9\r\n$8\r\nCPROCSET\r\n$6\r\n{0}000\r\n$6\r\n{0}001\r\n$6\r\n{0}002\r\n$6\r\n{0}003\r\n$6\r\n{0}000\r\n$6\r\n{0}001\r\n$6\r\n{0}002\r\n$6\r\n{0}003\r\n"u8; + byte[] cprocsetBuffer; + byte* cprocsetBufferPointer; + + void CreateExtensions() + { + // Register custom raw string command + server.Register.NewCommand("SETIFPM", CommandType.ReadModifyWrite, new SetIfPMCustomCommand(), new RespCommandsInfo { Arity = 4 }); + + // Register custom object type and commands + var factory = new MyDictFactory(); + server.Register.NewType(factory); + server.Register.NewCommand("MYDICTSET", CommandType.ReadModifyWrite, factory, new MyDictSet(), new RespCommandsInfo { Arity = 4 }); + server.Register.NewCommand("MYDICTGET", CommandType.Read, factory, new MyDictGet(), new RespCommandsInfo { Arity = 3 }); + + // Register custom transaction + server.Register.NewTransactionProc(CustomProcs.CustomTxnSet.CommandName, () => new CustomTxnSet(), + new RespCommandsInfo { Arity = CustomProcs.CustomTxnSet.Arity }); + + // Register custom procedure + server.Register.NewProcedure(CustomProcs.CustomProcSet.CommandName, new CustomProcSet(), + new RespCommandsInfo { Arity = CustomProcs.CustomProcSet.Arity }); + } + + public override void GlobalSetup() + { + base.GlobalSetup(); + CreateExtensions(); + + SetupOperation(ref setIfPmRequestBuffer, ref setIfPmRequestBufferPointer, SETIFPM); + SetupOperation(ref myDictSetGetRequestBuffer, ref myDictSetGetRequestBufferPointer, MYDICTSETGET); + SetupOperation(ref ctxnsetBuffer, ref ctxnsetBufferPointer, CTXNSET); + SetupOperation(ref cprocsetBuffer, ref cprocsetBufferPointer, CPROCSET); + + SlowConsumeMessage("*4\r\n$7\r\nSETIFPM\r\n$1\r\nk\r\n$3\r\nval\r\n$1\r\nv\r\n"u8); + SlowConsumeMessage("*4\r\n$9\r\nMYDICTSET\r\n$2\r\nck\r\n$1\r\nf\r\n$1\r\nv\r\n"u8); + SlowConsumeMessage(ctxnsetBuffer); + SlowConsumeMessage(cprocsetBuffer); + } + + [Benchmark] + public void CustomRawStringCommand() + { + _ = session.TryConsumeMessages(setIfPmRequestBufferPointer, setIfPmRequestBuffer.Length); + } + + [Benchmark] + public void CustomObjectCommand() + { + _ = session.TryConsumeMessages(myDictSetGetRequestBufferPointer, myDictSetGetRequestBuffer.Length); + } + + [Benchmark] + public void CustomTransaction() + { + _ = session.TryConsumeMessages(ctxnsetBufferPointer, ctxnsetBuffer.Length); + } + + [Benchmark] + public void CustomProcedure() + { + _ = session.TryConsumeMessages(cprocsetBufferPointer, cprocsetBuffer.Length); + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Operations/ObjectOperations.cs b/benchmark/BDN.benchmark/Operations/ObjectOperations.cs index 8dcd7ffa21..19b9fd52dc 100644 --- a/benchmark/BDN.benchmark/Operations/ObjectOperations.cs +++ b/benchmark/BDN.benchmark/Operations/ObjectOperations.cs @@ -1,10 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -using BDN.benchmark.CustomProcs; using BenchmarkDotNet.Attributes; -using Garnet; -using Garnet.server; namespace BDN.benchmark.Operations { @@ -30,41 +27,19 @@ public unsafe class ObjectOperations : OperationsBase byte[] hSetDelRequestBuffer; byte* hSetDelRequestBufferPointer; - static ReadOnlySpan MYDICTSETGET => "*4\r\n$9\r\nMYDICTSET\r\n$2\r\nck\r\n$1\r\nf\r\n$1\r\nv\r\n*3\r\n$9\r\nMYDICTGET\r\n$2\r\nck\r\n$1\r\nf\r\n"u8; - byte[] myDictSetGetRequestBuffer; - byte* myDictSetGetRequestBufferPointer; - - static ReadOnlySpan CPBSET => "*9\r\n$6\r\nCPBSET\r\n$6\r\n{0}000\r\n$6\r\n{0}001\r\n$6\r\n{0}002\r\n$6\r\n{0}003\r\n$6\r\n{0}000\r\n$6\r\n{0}001\r\n$6\r\n{0}002\r\n$6\r\n{0}003\r\n"u8; - byte[] cpbsetBuffer; - byte* cpbsetBufferPointer; - - void CreateExtensions() - { - var factory = new MyDictFactory(); - server.Register.NewType(factory); - server.Register.NewCommand("MYDICTSET", CommandType.ReadModifyWrite, factory, new MyDictSet(), new RespCommandsInfo { Arity = 4 }); - server.Register.NewCommand("MYDICTGET", CommandType.Read, factory, new MyDictGet(), new RespCommandsInfo { Arity = 3 }); - server.Register.NewTransactionProc(CustomProcs.CustomProcSet.CommandName, () => new CustomProcSet(), new RespCommandsInfo { Arity = CustomProcs.CustomProcSet.Arity }); - } - public override void GlobalSetup() { base.GlobalSetup(); - CreateExtensions(); SetupOperation(ref zAddRemRequestBuffer, ref zAddRemRequestBufferPointer, ZADDREM); SetupOperation(ref lPushPopRequestBuffer, ref lPushPopRequestBufferPointer, LPUSHPOP); SetupOperation(ref sAddRemRequestBuffer, ref sAddRemRequestBufferPointer, SADDREM); SetupOperation(ref hSetDelRequestBuffer, ref hSetDelRequestBufferPointer, HSETDEL); - SetupOperation(ref myDictSetGetRequestBuffer, ref myDictSetGetRequestBufferPointer, MYDICTSETGET); - SetupOperation(ref cpbsetBuffer, ref cpbsetBufferPointer, CPBSET); // Pre-populate data SlowConsumeMessage("*4\r\n$4\r\nZADD\r\n$1\r\nc\r\n$1\r\n1\r\n$1\r\nd\r\n"u8); SlowConsumeMessage("*3\r\n$5\r\nLPUSH\r\n$1\r\nd\r\n$1\r\nf\r\n"u8); SlowConsumeMessage("*3\r\n$4\r\nSADD\r\n$1\r\ne\r\n$1\r\nb\r\n"u8); SlowConsumeMessage("*3\r\n$4\r\nHSET\r\n$1\r\nf\r\n$1\r\nb\r\n$1\r\nb\r\n"u8); - SlowConsumeMessage("*4\r\n$9\r\nMYDICTSET\r\n$2\r\nck\r\n$1\r\nf\r\n$1\r\nv\r\n"u8); - SlowConsumeMessage(cpbsetBuffer); } [Benchmark] @@ -90,17 +65,5 @@ public void HSetDel() { _ = session.TryConsumeMessages(hSetDelRequestBufferPointer, hSetDelRequestBuffer.Length); } - - [Benchmark] - public void MyDictSetGet() - { - _ = session.TryConsumeMessages(myDictSetGetRequestBufferPointer, myDictSetGetRequestBuffer.Length); - } - - [Benchmark] - public void CustomProcSet() - { - _ = session.TryConsumeMessages(cpbsetBufferPointer, cpbsetBuffer.Length); - } } } \ No newline at end of file