Skip to content

Commit 09499a0

Browse files
authored
improve rust performance (#944)
* rust specialize get_u8_at & put_u8_at improve performance use copy_from_slice instead of split_at when r/w u8 array * remove pointless comment * get_bytes_at crate scoped * fix java style lints
1 parent 4454c85 commit 09499a0

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

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

+17-6
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,21 @@ 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(crate) fn get_bytes_at<const N: usize>(slice: &[u8], index: usize) -> [u8; N] {\n");
179+
indent(writer, 2, "slice[index..index+N].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+
uniquePrimitiveTypes.remove("u8");
187+
indent(writer, 0, "\n");
188+
indent(writer, 1, "#[inline]\n");
189+
indent(writer, 1, "pub fn get_u8_at(&self, index: usize) -> u8 {\n");
190+
indent(writer, 2, "self.data[index]\n");
191+
indent(writer, 1, "}\n");
192+
186193
for (final String primitiveType : uniquePrimitiveTypes)
187194
{
188195
// get_<primitive>_at
@@ -197,7 +204,7 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder)
197204
indent(writer, 0, "\n");
198205
indent(writer, 1, "#[inline]\n");
199206
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");
207+
indent(writer, 2, "&self.data[index..index+len]\n");
201208
indent(writer, 1, "}\n\n");
202209

203210
writer.append("}\n");
@@ -219,16 +226,20 @@ static void generateWriteBuf(final Writer writer, final ByteOrder byteOrder) thr
219226
indent(writer, 1, "#[inline]\n");
220227
indent(writer, 1,
221228
"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");
229+
indent(writer, 2, "self.data[index..index + COUNT].copy_from_slice(&bytes);\n");
225230
indent(writer, 2, "COUNT\n");
226231
indent(writer, 1, "}\n\n");
227232

228233
final LinkedHashSet<String> uniquePrimitiveTypes
229234
= new LinkedHashSet<>(TYPE_NAME_BY_PRIMITIVE_TYPE_MAP.values());
230235
final String endianness = byteOrder == LITTLE_ENDIAN ? "le" : "be";
231236

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");
242+
232243
for (final String primitiveType : uniquePrimitiveTypes)
233244
{
234245
// put_<primitive>_at

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

+15
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,13 @@ 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.equals("u8"))
380+
{
381+
indent(sb, level + 1, "buf.put_bytes_at(offset, value);\n");
382+
indent(sb, level, "}\n\n");
383+
return;
384+
}
385+
379386
for (int i = 0; i < arrayLength; i++)
380387
{
381388
if (i == 0)
@@ -646,6 +653,14 @@ private static void generatePrimitiveArrayDecoder(
646653
}
647654

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

0 commit comments

Comments
 (0)