Skip to content

Commit 3c7273c

Browse files
committed
rust specialize get_u8_at & put_u8_at improve performance
use copy_from_slice instead of split_at when r/w u8 array
1 parent b4ec154 commit 3c7273c

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,22 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder)
175175
indent(writer, 1, "}\n\n");
176176

177177
indent(writer, 1, "#[inline]\n");
178-
indent(writer, 1, "fn get_bytes_at<const COUNT: usize>(slice: &[u8], index: usize) -> [u8; COUNT] {\n");
179-
indent(writer, 2, "Self::get_bytes(slice.split_at(index).1.split_at(COUNT).0)\n");
178+
indent(writer, 1, "pub fn get_bytes_at<const COUNT: usize>(slice: &[u8], index: usize) -> [u8; COUNT] {\n");
179+
indent(writer, 2, "slice[index..index+COUNT].try_into().expect(\"slice with incorrect length\")\n");
180180
indent(writer, 1, "}\n");
181181

182182
final LinkedHashSet<String> uniquePrimitiveTypes
183183
= new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values());
184184
final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be";
185185

186+
// get_u8_at
187+
uniquePrimitiveTypes.remove("u8");
188+
indent(writer, 0, "\n");
189+
indent(writer, 1, "#[inline]\n");
190+
indent(writer, 1, "pub fn get_u8_at(&self, index: usize) -> u8 {\n");
191+
indent(writer, 2, "self.data[index]\n");
192+
indent(writer, 1, "}\n");
193+
186194
for (final String primitiveType : uniquePrimitiveTypes)
187195
{
188196
// get_<primitive>_at
@@ -197,7 +205,7 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder)
197205
indent(writer, 0, "\n");
198206
indent(writer, 1, "#[inline]\n");
199207
indent(writer, 1, "pub fn get_slice_at(&self, index: usize, len: usize) -> &[u8] {\n");
200-
indent(writer, 2, "self.data.split_at(index).1.split_at(len).0\n");
208+
indent(writer, 2, "&self.data[index..index+len]\n");
201209
indent(writer, 1, "}\n\n");
202210

203211
writer.append("}\n");
@@ -219,15 +227,18 @@ static void generateWriteBuf(final Writer writer, final ByteOrder byteOrder) thr
219227
indent(writer, 1, "#[inline]\n");
220228
indent(writer, 1,
221229
"pub fn put_bytes_at<const COUNT: usize>(&mut self, index: usize, bytes: [u8; COUNT]) -> usize {\n");
222-
indent(writer, 2, "for (i, byte) in bytes.iter().enumerate() {\n");
223-
indent(writer, 3, "self.data[index + i] = *byte;\n");
224-
indent(writer, 2, "}\n");
230+
indent(writer, 2, "self.data[index..index + COUNT].copy_from_slice(&bytes);\n");
225231
indent(writer, 2, "COUNT\n");
226232
indent(writer, 1, "}\n\n");
227233

228234
final LinkedHashSet<String> uniquePrimitiveTypes
229235
= new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values());
230236
final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be";
237+
uniquePrimitiveTypes.remove("u8");
238+
indent(writer, 1, "#[inline]\n");
239+
indent(writer, 1, "pub fn put_u8_at(&mut self, index: usize, value: u8) {\n");
240+
indent(writer, 2, "self.data[index] = value;\n");
241+
indent(writer, 1, "}\n\n");
231242

232243
for (final String primitiveType : uniquePrimitiveTypes)
233244
{

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,12 @@ private static void generatePrimitiveEncoder(
376376
indent(sb, level + 1, "let offset = self.%s;\n", getBufOffset(typeToken));
377377
indent(sb, level + 1, "let buf = self.get_buf_mut();\n");
378378

379+
if (rustPrimitiveType == "u8") {
380+
indent(sb, level + 1, "buf.put_bytes_at(offset, value);\n");
381+
indent(sb, level, "}\n\n");
382+
return;
383+
}
384+
379385
for (int i = 0; i < arrayLength; i++)
380386
{
381387
if (i == 0)
@@ -646,6 +652,14 @@ private static void generatePrimitiveArrayDecoder(
646652
}
647653

648654
indent(sb, level + 1, "let buf = self.get_buf();\n");
655+
if (rustPrimitiveType == "u8")
656+
{
657+
indent(sb, level + 1, "ReadBuf::get_bytes_at(buf.data, self.%s)\n",
658+
getBufOffset(typeToken));
659+
indent(sb, level, "}\n\n");
660+
return;
661+
}
662+
649663
indent(sb, level + 1, "[\n");
650664
for (int i = 0; i < arrayLength; i++)
651665
{

0 commit comments

Comments
 (0)