From 1d0a2fc78826fdaf872fe8da7329291e7150672b Mon Sep 17 00:00:00 2001 From: lumber1000 <45400511+lumber1000@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:52:32 +0400 Subject: [PATCH] jmh tests added --- build.gradle | 6 + .../th2/codec/fixng/FixNgCodecBenchmark.kt | 62 ++++++++++ .../th2/codec/fixng/FixNgCodecTest.kt | 113 +++++++++--------- 3 files changed, 125 insertions(+), 56 deletions(-) create mode 100644 src/jmh/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecBenchmark.kt diff --git a/build.gradle b/build.gradle index 83a209b..bda24d6 100644 --- a/build.gradle +++ b/build.gradle @@ -3,11 +3,13 @@ plugins { id "com.exactpro.th2.gradle.component" version "0.1.1" id "org.jetbrains.kotlin.jvm" version "$kotlin_version" id "org.jetbrains.kotlin.kapt" version "$kotlin_version" + id "me.champeau.jmh" version "0.7.2" } ext { sailfishVersion = '3.3.241' commonVersion = '5.14.0-dev' + jmhVersion = '1.37' } group = 'com.exactpro.th2' @@ -89,6 +91,10 @@ dependencies { annotationProcessor "com.google.auto.service:auto-service:1.1.1" kapt "com.google.auto.service:auto-service:1.1.1" + jmh "org.openjdk.jmh:jmh-core:$jmhVersion" + jmh "org.openjdk.jmh:jmh-generator-annprocess:$jmhVersion" + jmh "org.openjdk.jmh:jmh-generator-bytecode:$jmhVersion" + testImplementation "org.junit.jupiter:junit-jupiter" testImplementation "org.jetbrains.kotlin:kotlin-test-junit5" testImplementation "org.assertj:assertj-core:3.26.3" diff --git a/src/jmh/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecBenchmark.kt b/src/jmh/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecBenchmark.kt new file mode 100644 index 0000000..32e0e53 --- /dev/null +++ b/src/jmh/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecBenchmark.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2024 Exactpro (Exactpro Systems Limited) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.exactpro.th2.codec.fixng + +import com.exactpro.sf.common.messages.structures.IDictionaryStructure +import com.exactpro.sf.common.messages.structures.loaders.XmlDictionaryStructureLoader +import com.exactpro.th2.codec.api.IReportingContext +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.MessageGroup +import com.exactpro.th2.common.schema.message.impl.rabbitmq.transport.RawMessage +import io.netty.buffer.Unpooled +import org.openjdk.jmh.annotations.Benchmark +import org.openjdk.jmh.annotations.BenchmarkMode +import org.openjdk.jmh.annotations.Mode +import org.openjdk.jmh.annotations.Scope +import org.openjdk.jmh.annotations.State + +@State(Scope.Benchmark) +open class FixNgCodecBenchmark { + private val dictionary: IDictionaryStructure = FixNgCodecTest::class.java.classLoader + .getResourceAsStream("dictionary.xml") + .use(XmlDictionaryStructureLoader()::load) + + private val parsedMessage = FixNgCodecTest.createParsedMessage() + private val codec = FixNgCodec(dictionary, FixNgCodecSettings(dictionary = "", decodeValuesToStrings = false)) + private val rawBody = Unpooled.wrappedBuffer(FixNgCodecTest.MSG_CORRECT.toByteArray(Charsets.US_ASCII)) + private val rawGroup = MessageGroup(listOf(RawMessage(id = parsedMessage.id, eventId = parsedMessage.eventId, body = rawBody))) + private val parsedGroup = MessageGroup(listOf(parsedMessage)) + + @Benchmark + @BenchmarkMode(Mode.Throughput) + fun encodeFixMessage() { + codec.encode(parsedGroup, context) + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + fun parseFixMessage() { + rawBody.resetReaderIndex() + codec.decode(rawGroup, context) + } + + companion object { + private val context = object : IReportingContext { + override fun warning(message: String) { } + override fun warnings(messages: Iterable) { } + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecTest.kt b/src/test/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecTest.kt index d69346c..5759471 100644 --- a/src/test/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecTest.kt +++ b/src/test/kotlin/com/exactpro/th2/codec/fixng/FixNgCodecTest.kt @@ -305,61 +305,7 @@ class FixNgCodecTest { else -> value.toString() } - private val parsedMessage = ParsedMessage( - MessageId("test_alias", Direction.OUTGOING, 0L, Instant.now(), emptyList()), - EventId("test_id", "test_book", "test_scope", Instant.now()), - "ExecutionReport", - mutableMapOf("encode-mode" to "dirty"), - PROTOCOL, - mutableMapOf( - "header" to mutableMapOf( - "MsgSeqNum" to 10947, - "SenderCompID" to "SENDER", - "SendingTime" to LocalDateTime.parse("2023-04-19T10:36:07.415088"), - "TargetCompID" to "RECEIVER", - "BeginString" to "FIXT.1.1", - "BodyLength" to 295, - "MsgType" to "8" - ), - "ExecID" to "495504662", - "ClOrdID" to "zSuNbrBIZyVljs", - "OrigClOrdID" to "zSuNbrBIZyVljs", - "OrderID" to "49415882", - "ExecType" to '0', - "OrdStatus" to '0', - "LeavesQty" to 500, - "CumQty" to BigDecimal(500), - "SecurityID" to "NWDR", - "SecurityIDSource" to "8", - "TradingParty" to mutableMapOf( - "NoPartyIDs" to mutableListOf( - mutableMapOf( - "PartyID" to "NGALL1FX01", - "PartyIDSource" to 'D', - "PartyRole" to 76 - ), - mutableMapOf( - "PartyID" to "0", - "PartyIDSource" to 'P', - "PartyRole" to 3 - ) - ) - ), - "Account" to "test", - "OrdType" to 'A', - "TimeInForce" to '0', - "Side" to 'B', - "Symbol" to "ABC", - "OrderQty" to 500, - "Price" to 1000, - "Unknown" to "500", - "TransactTime" to LocalDateTime.parse("2018-02-05T10:38:08.000008"), - "trailer" to mutableMapOf( - "CheckSum" to "191" - ) - ) - ) - + private val parsedMessage = createParsedMessage() private val parsedBody: MutableMap = parsedMessage.body as MutableMap private val expectedParsedMessage = ParsedMessage( @@ -442,7 +388,7 @@ class FixNgCodecTest { companion object { private const val DIRTY_MODE_WARNING_PREFIX = "Dirty mode WARNING: " - private const val MSG_CORRECT = "8=FIXT.1.1\u00019=295\u000135=8\u000149=SENDER\u000156=RECEIVER\u000134=10947\u000152=20230419-10:36:07.415088\u000117=495504662\u000111=zSuNbrBIZyVljs\u000141=zSuNbrBIZyVljs\u000137=49415882\u0001150=0\u000139=0\u0001151=500\u000114=500\u000148=NWDR\u000122=8\u0001453=2\u0001448=NGALL1FX01\u0001447=D\u0001452=76\u0001448=0\u0001447=P\u0001452=3\u00011=test\u000140=A\u000159=0\u000154=B\u000155=ABC\u000138=500\u000144=1000\u000147=500\u000160=20180205-10:38:08.000008\u000110=191\u0001" + const val MSG_CORRECT = "8=FIXT.1.1\u00019=295\u000135=8\u000149=SENDER\u000156=RECEIVER\u000134=10947\u000152=20230419-10:36:07.415088\u000117=495504662\u000111=zSuNbrBIZyVljs\u000141=zSuNbrBIZyVljs\u000137=49415882\u0001150=0\u000139=0\u0001151=500\u000114=500\u000148=NWDR\u000122=8\u0001453=2\u0001448=NGALL1FX01\u0001447=D\u0001452=76\u0001448=0\u0001447=P\u0001452=3\u00011=test\u000140=A\u000159=0\u000154=B\u000155=ABC\u000138=500\u000144=1000\u000147=500\u000160=20180205-10:38:08.000008\u000110=191\u0001" private const val MSG_CORRECT_WITHOUT_BODY = "8=FIX.4.2\u00019=55\u000135=0\u000134=125\u000149=MZHOT0\u000152=20240801-08:03:01.229\u000156=INET\u000110=039\u0001" private const val MSG_ADDITIONAL_FIELD_DICT = "8=FIXT.1.1\u00019=305\u000135=8\u000149=SENDER\u000156=RECEIVER\u000134=10947\u000152=20230419-10:36:07.415088\u000117=495504662\u000111=zSuNbrBIZyVljs\u000141=zSuNbrBIZyVljs\u000137=49415882\u0001150=0\u000139=0\u0001151=500\u000114=500\u000148=NWDR\u000122=8\u0001453=2\u0001448=NGALL1FX01\u0001447=D\u0001452=76\u0001448=0\u0001447=P\u0001452=3\u00011=test\u000140=A\u000159=0\u000154=B\u000155=ABC\u000138=500\u000144=1000\u000147=500\u000160=20180205-10:38:08.000008\u0001461=12345\u000110=143\u0001" private const val MSG_ADDITIONAL_FIELD_NO_DICT = "8=FIXT.1.1\u00019=305\u000135=8\u000149=SENDER\u000156=RECEIVER\u000134=10947\u000152=20230419-10:36:07.415088\u000117=495504662\u000111=zSuNbrBIZyVljs\u000141=zSuNbrBIZyVljs\u000137=49415882\u0001150=0\u000139=0\u0001151=500\u000114=500\u000148=NWDR\u000122=8\u0001453=2\u0001448=NGALL1FX01\u0001447=D\u0001452=76\u0001448=0\u0001447=P\u0001452=3\u00011=test\u000140=A\u000159=0\u000154=B\u000155=ABC\u000138=500\u000144=1000\u000147=500\u000160=20180205-10:38:08.000008\u00019999=54321\u000110=097\u0001" @@ -468,5 +414,60 @@ class FixNgCodecTest { .appendPattern("HH:mm:ss") .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 9, true) .toFormatter() + + fun createParsedMessage() = ParsedMessage( + MessageId("test_alias", Direction.OUTGOING, 0L, Instant.now(), emptyList()), + EventId("test_id", "test_book", "test_scope", Instant.now()), + "ExecutionReport", + mutableMapOf("encode-mode" to "dirty"), + PROTOCOL, + mutableMapOf( + "header" to mutableMapOf( + "MsgSeqNum" to 10947, + "SenderCompID" to "SENDER", + "SendingTime" to LocalDateTime.parse("2023-04-19T10:36:07.415088"), + "TargetCompID" to "RECEIVER", + "BeginString" to "FIXT.1.1", + "BodyLength" to 295, + "MsgType" to "8" + ), + "ExecID" to "495504662", + "ClOrdID" to "zSuNbrBIZyVljs", + "OrigClOrdID" to "zSuNbrBIZyVljs", + "OrderID" to "49415882", + "ExecType" to '0', + "OrdStatus" to '0', + "LeavesQty" to 500, + "CumQty" to BigDecimal(500), + "SecurityID" to "NWDR", + "SecurityIDSource" to "8", + "TradingParty" to mutableMapOf( + "NoPartyIDs" to mutableListOf( + mutableMapOf( + "PartyID" to "NGALL1FX01", + "PartyIDSource" to 'D', + "PartyRole" to 76 + ), + mutableMapOf( + "PartyID" to "0", + "PartyIDSource" to 'P', + "PartyRole" to 3 + ) + ) + ), + "Account" to "test", + "OrdType" to 'A', + "TimeInForce" to '0', + "Side" to 'B', + "Symbol" to "ABC", + "OrderQty" to 500, + "Price" to 1000, + "Unknown" to "500", + "TransactTime" to LocalDateTime.parse("2018-02-05T10:38:08.000008"), + "trailer" to mutableMapOf( + "CheckSum" to "191" + ) + ) + ) } } \ No newline at end of file