Hacker News new | ask | show | jobs
by scoutt 1596 days ago
> in Rust you need to implement (de)serializing logic

Hmm. Well that sucks. It might be slower than reading into a struct directly (does more IO calls, there is more code to execute, probably uses more memory). My focus is on embedded applications, so "the less, the better".

> no need for unsafe

Can you point out an example on reading a bunch of structs from a file? Without std? Now I'm really curious.

> you have this weird assumption

You are probably right. I intended to use Rust in embedded as I said before so I thought a system language like Rust could fit. But you are right and the more I read (docs and comments like yours) I realize it's not C, and Rust may require extra steps and resources to achieve the same things I can do in C. With consequential hit on performance/code size/whatever, that it's a thing to consider seriously in constrained environments.

3 comments

Rust works great in embedded. You do have to learn some things about how to get binary sizes down, depending on how resource constrained you are. If you're on a device that's running Linux, you probably don't need to think about it at all. If you're on a device and writing 100% of the code yourself, you may have to watch out for certain things, like formatting code, that can add a bunch of bloat, and choose alternatives.

At work we have a de novo microkernel we're using for the firmware of a few things inside of our product. A recent build we did to check on binary size of OS + 5 simple tasks using 22kb of flash and 3.5 kb of RAM. Those tasks are all separately compiled programs, it all gets put together on one single image to flash.

If you're talking 8 bit micros, you run into platform support issues before you even get to the binary size stuff, but if you're on Arm, even the low end, size is not the primary issue when it comes to doing Rust projects.

>Can you point out an example on reading a bunch of structs from a file? Without std? Now I'm really curious.

Not really, but here is really simple example:

  use std::fs::File;
  use std::io::Read;
  
  #[derive(Debug)]
  struct Point {
      x: i32,
      y: i32,
  }
  
  fn bytes2point(buf: [u8; 8]) -> Point {
      Point {
          // Slices to arrays is a bit unwieldy...
          x: i32::from_le_bytes(buf[..4].try_into().unwrap()),
          y: i32::from_le_bytes(buf[4..].try_into().unwrap()),
      }
  }
  
  fn main() {
      let mut buf: [u8; 8] = [0; 8];
      let mut file: File = File::open("data.txt").unwrap();
      Read::read(&mut file, &mut buf).unwrap();
      let point: Point = bytes2point(buf);
      println!("{:?}", point);
  }
It doesn't do any extra i/o compared to C. Std is only used for filesystem access and printing. It does require extra buffer.
Thank you.

I see. I'm looking now at how to load DOOM WAD files in Rust (https://github.com/bjt0/rs_wad/blob/master/src/wad.rs#L105) as an example, and I see it uses your method (even if it seems to store each piece in individual variables to then copy them into the struct).

It's not as straightforward as one would expect (as you say, it requires an extra buffer and parsing, but no extra IO). I surely wouldn't get to the solution by myself.

I'd be surprised if you see that Rust code is significantly slower than equivalent C code; this isn't how it pans out in most benchmarks. The killer for Rust is executable binary size, which even with no-std and other tricks can still balloon to an enormous size.