From 3c7273cbe85d89328916eed6f14aa7ae5295f1e6 Mon Sep 17 00:00:00 2001 From: holygits Date: Sat, 10 Jun 2023 16:47:35 +1200 Subject: [PATCH 1/4] rust specialize get_u8_at & put_u8_at improve performance use copy_from_slice instead of split_at when r/w u8 array --- .../sbe/generation/rust/LibRsDef.java | 23 ++++++++++++++----- .../sbe/generation/rust/RustGenerator.java | 14 +++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index 349bc79c9..60f12b57d 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -175,14 +175,22 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder) indent(writer, 1, "}\n\n"); indent(writer, 1, "#[inline]\n"); - indent(writer, 1, "fn get_bytes_at(slice: &[u8], index: usize) -> [u8; COUNT] {\n"); - indent(writer, 2, "Self::get_bytes(slice.split_at(index).1.split_at(COUNT).0)\n"); + indent(writer, 1, "pub fn get_bytes_at(slice: &[u8], index: usize) -> [u8; COUNT] {\n"); + indent(writer, 2, "slice[index..index+COUNT].try_into().expect(\"slice with incorrect length\")\n"); indent(writer, 1, "}\n"); final LinkedHashSet uniquePrimitiveTypes = new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values()); final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be"; + // get_u8_at + uniquePrimitiveTypes.remove("u8"); + indent(writer, 0, "\n"); + indent(writer, 1, "#[inline]\n"); + indent(writer, 1, "pub fn get_u8_at(&self, index: usize) -> u8 {\n"); + indent(writer, 2, "self.data[index]\n"); + indent(writer, 1, "}\n"); + for (final String primitiveType : uniquePrimitiveTypes) { // get__at @@ -197,7 +205,7 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder) indent(writer, 0, "\n"); indent(writer, 1, "#[inline]\n"); indent(writer, 1, "pub fn get_slice_at(&self, index: usize, len: usize) -> &[u8] {\n"); - indent(writer, 2, "self.data.split_at(index).1.split_at(len).0\n"); + indent(writer, 2, "&self.data[index..index+len]\n"); indent(writer, 1, "}\n\n"); writer.append("}\n"); @@ -219,15 +227,18 @@ static void generateWriteBuf(final Writer writer, final ByteOrder byteOrder) thr indent(writer, 1, "#[inline]\n"); indent(writer, 1, "pub fn put_bytes_at(&mut self, index: usize, bytes: [u8; COUNT]) -> usize {\n"); - indent(writer, 2, "for (i, byte) in bytes.iter().enumerate() {\n"); - indent(writer, 3, "self.data[index + i] = *byte;\n"); - indent(writer, 2, "}\n"); + indent(writer, 2, "self.data[index..index + COUNT].copy_from_slice(&bytes);\n"); indent(writer, 2, "COUNT\n"); indent(writer, 1, "}\n\n"); final LinkedHashSet uniquePrimitiveTypes = new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values()); final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be"; + uniquePrimitiveTypes.remove("u8"); + indent(writer, 1, "#[inline]\n"); + indent(writer, 1, "pub fn put_u8_at(&mut self, index: usize, value: u8) {\n"); + indent(writer, 2, "self.data[index] = value;\n"); + indent(writer, 1, "}\n\n"); for (final String primitiveType : uniquePrimitiveTypes) { diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java index 051446323..f00618654 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java @@ -376,6 +376,12 @@ private static void generatePrimitiveEncoder( indent(sb, level + 1, "let offset = self.%s;\n", getBufOffset(typeToken)); indent(sb, level + 1, "let buf = self.get_buf_mut();\n"); + if (rustPrimitiveType == "u8") { + indent(sb, level + 1, "buf.put_bytes_at(offset, value);\n"); + indent(sb, level, "}\n\n"); + return; + } + for (int i = 0; i < arrayLength; i++) { if (i == 0) @@ -646,6 +652,14 @@ private static void generatePrimitiveArrayDecoder( } indent(sb, level + 1, "let buf = self.get_buf();\n"); + if (rustPrimitiveType == "u8") + { + indent(sb, level + 1, "ReadBuf::get_bytes_at(buf.data, self.%s)\n", + getBufOffset(typeToken)); + indent(sb, level, "}\n\n"); + return; + } + indent(sb, level + 1, "[\n"); for (int i = 0; i < arrayLength; i++) { From 14f6b62d9a9fca585e6bf3821bf49a0b9a3d0dc9 Mon Sep 17 00:00:00 2001 From: holygits Date: Sat, 10 Jun 2023 17:02:15 +1200 Subject: [PATCH 2/4] remove pointless comment --- .../java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index 60f12b57d..a2192b09c 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -183,7 +183,6 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder) = new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values()); final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be"; - // get_u8_at uniquePrimitiveTypes.remove("u8"); indent(writer, 0, "\n"); indent(writer, 1, "#[inline]\n"); @@ -234,6 +233,7 @@ static void generateWriteBuf(final Writer writer, final ByteOrder byteOrder) thr final LinkedHashSet uniquePrimitiveTypes = new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values()); final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be"; + uniquePrimitiveTypes.remove("u8"); indent(writer, 1, "#[inline]\n"); indent(writer, 1, "pub fn put_u8_at(&mut self, index: usize, value: u8) {\n"); From 9440f551c0ccb2642e3cad6ad64024eef249125a Mon Sep 17 00:00:00 2001 From: holygits Date: Sat, 10 Jun 2023 17:05:27 +1200 Subject: [PATCH 3/4] get_bytes_at crate scoped --- .../java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index a2192b09c..283f9c6bf 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -175,7 +175,7 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder) indent(writer, 1, "}\n\n"); indent(writer, 1, "#[inline]\n"); - indent(writer, 1, "pub fn get_bytes_at(slice: &[u8], index: usize) -> [u8; COUNT] {\n"); + indent(writer, 1, "pub(crate) fn get_bytes_at(slice: &[u8], index: usize) -> [u8; COUNT] {\n"); indent(writer, 2, "slice[index..index+COUNT].try_into().expect(\"slice with incorrect length\")\n"); indent(writer, 1, "}\n"); From e3a2971c743282573a5da27ae94cc1a21be88a75 Mon Sep 17 00:00:00 2001 From: holygits Date: Sun, 18 Jun 2023 11:29:17 +1200 Subject: [PATCH 4/4] fix java style lints --- .../uk/co/real_logic/sbe/generation/rust/LibRsDef.java | 4 ++-- .../co/real_logic/sbe/generation/rust/RustGenerator.java | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index 283f9c6bf..3d38b28aa 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -175,8 +175,8 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder) indent(writer, 1, "}\n\n"); indent(writer, 1, "#[inline]\n"); - indent(writer, 1, "pub(crate) fn get_bytes_at(slice: &[u8], index: usize) -> [u8; COUNT] {\n"); - indent(writer, 2, "slice[index..index+COUNT].try_into().expect(\"slice with incorrect length\")\n"); + indent(writer, 1, "pub(crate) fn get_bytes_at(slice: &[u8], index: usize) -> [u8; N] {\n"); + indent(writer, 2, "slice[index..index+N].try_into().expect(\"slice with incorrect length\")\n"); indent(writer, 1, "}\n"); final LinkedHashSet uniquePrimitiveTypes diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java index f00618654..3b3e42bbb 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java @@ -376,7 +376,8 @@ private static void generatePrimitiveEncoder( indent(sb, level + 1, "let offset = self.%s;\n", getBufOffset(typeToken)); indent(sb, level + 1, "let buf = self.get_buf_mut();\n"); - if (rustPrimitiveType == "u8") { + if (rustPrimitiveType.equals("u8")) + { indent(sb, level + 1, "buf.put_bytes_at(offset, value);\n"); indent(sb, level, "}\n\n"); return; @@ -652,10 +653,10 @@ private static void generatePrimitiveArrayDecoder( } indent(sb, level + 1, "let buf = self.get_buf();\n"); - if (rustPrimitiveType == "u8") + if (rustPrimitiveType.equals("u8")) { indent(sb, level + 1, "ReadBuf::get_bytes_at(buf.data, self.%s)\n", - getBufOffset(typeToken)); + getBufOffset(typeToken)); indent(sb, level, "}\n\n"); return; }