How to learn modern Rust
A guide to the adventurer.
Table of Contents
- Learn Rust deeply one step after the other
- Text Processing in Rust
- How Rust maps to memory and lifetimes annotations in Rust
- How to deal with Circular References and Ownership
- Polymorphism in Rust
- Rust Testing and TDD - Test Driven Development
- Systems programming in Rust
- Background in systems programming
- Writing Compilers in Rust
- Contributing to the Rust Compiler rustc
- WebAssembly in Rust - WASM
- WebFrameworks in Rust - Similar to React Angular or Vue
- Python extended with Rust and running a Python interpreter inside Rust
- Rust with inline Python
- Rust on or for the Raspberry Pi
- Raspberry Pi Bare Metal
- Embedded Rust
- Embedded Rust crates and code size optimization
- Embedded Rust with STM32 BluePill - STM32F103
- Embedded Rust with Raspberry Pi Pico - 4 dollars board
- Embedded Rust with ESP32
- Links
- Rust Foundation
- Rust Blogs
- Rust Youtube Channels
- GUI programming in Rust
- Audio in Rust
- Faster Compilation - Linker times in Linux and Unix ELF
- Machine Learning for Rust
- Rust VSCode plugins
- Rust Debugger
- Rust Error Handling
- Tips and Tricks
- GC for Rust - Garbage Collector
- Programming Parallel Computers - Optimization guide C Plus Plus and Rust
- Rust Optimization - Compilation modes and flags
- Rust bounds check removal
- Notes - General
- Notes on optimization
- Rust substring processing
- Macros in Rust
- Good way to learn about the topic of computers and programming
- For a good challenge do the NAND To Tetris in Rust
- All my other guides
- Have fun!
Learn Rust deeply one step after the other
Rust is an incredible powerful programming language. It is fast, compiled, without a runtime and it brings new concepts of safety to programming.
It is the most beloved language for five years in a row in Stack Overflow users pool.
To learn Rust go through the following content in the listed order, the majority of the content is free.
-
Why Developers Love Rust
https://ibraheem.ca/posts/why-devs-love-rust/ -
Video - Rust Crash Course - Rustlang
https://www.youtube.com/watch?v=zF34dRivLOw -
Video - Introduction to Rust Part 1
https://www.youtube.com/watch?v=WnWGO-tLtLA -
Video - Introduction to Rust Part 2
https://www.youtube.com/watch?v=lLWchWTUFOQ -
Video - Rust for the impatient - No Boilerplate
https://www.youtube.com/watch?v=br3GIIQeefY -
A half-hour to learn Rust - fasterThanLime Blog
https://fasterthanli.me/articles/a-half-hour-to-learn-rust -
Videos - Microsoft Beginner's Series to Rust
https://www.youtube.com/playlist?list=PLlrxD0HtieHjbTjrchBwOVks_sr8EVW1x
GitHub Code
https://github.com/microsoft/beginners-series-rust -
The Tour of Rust
https://tourofrust.com/ -
A Rust experienced developer teaches a C++ experienced developer (Jason Turner) about Rust, from zero.
Jonathan Teaches Jason Rust - Part 1 - C++ Weekly
https://www.youtube.com/watch?v=EzQ7YIIo1rY
Jonathan Teaches Jason Rust - Part 2 - C++ Weekly
https://www.youtube.com/watch?v=Y5-ZgxfQvpc -
The Rust Programming Language Book
by Steve Klabnik and Carol Nichols, with contributions from the Rust Community
https://doc.rust-lang.org/stable/book/ -
Rust Language Cheat Sheet
https://cheats.rs/ -
Rustlings
Small exercises to get you used to reading and writing Rust code.
https://github.com/rust-lang/rustlings -
Videos - Intro to Rustlang - Tensor Programming
https://www.youtube.com/watch?v=EYqceb2AnkU&list=PLJbE2Yu2zumDF6BX6_RdPisRVHgzV02NW -
Videos - Rustlang Project - Tensor Programming
https://www.youtube.com/watch?v=-Jp7sabBCp4&list=PLJbE2Yu2zumDD5vy2BuSHvFZU0a6RDmgb -
Standard collections - std info and how to choose the correct collection
https://doc.rust-lang.org/std/collections/index.html -
Trivia About Rust Types: An Authorized Transcription of Jon Gjengset’s Twitter Thread
https://www.thecodedmessage.com/posts/trivia-rust-types/ -
Video - Unsafe & FFI in Rust
https://www.youtube.com/watch?v=LFFbTeU25pE -
Rust by Example Book
https://doc.rust-lang.org/rust-by-example/ -
Study carefully the methods of
Option
in the documentation, they are used in all Rust programs
https://doc.rust-lang.org/beta/std/option/index.html -
Study carefully the methods of
Result
in the documentation, they are used in all Rust programs
https://doc.rust-lang.org/beta/std/result/index.html -
Command Line Applications in Rust - Book
https://rust-cli.github.io/book/in-depth/docs.html -
The Rust Standard Library documentation
https://doc.rust-lang.org/std/ -
Learn Rust With Entirely Too Many Linked Lists - Book
https://rust-unofficial.github.io/too-many-lists/ -
Rust Design Patterns - Book
https://rust-unofficial.github.io/patterns/ -
Effective Rust - Book
https://www.lurklurk.org/effective-rust/ -
The Rust Cookbook - Book
https://rust-lang-nursery.github.io/rust-cookbook/ -
The Cargo Book
https://doc.rust-lang.org/cargo/index.html -
Guide trough of the Advent of Code 2020
https://fasterthanli.me/series/advent-of-code-2020 -
Rust API Guidelines Book
https://rust-lang.github.io/api-guidelines/about.html -
The Rust Reference Book
https://doc.rust-lang.org/stable/reference/ -
The Rustonomicon - The Dark Arts of Unsafe Rust - Book
https://doc.rust-lang.org/nomicon/ -
The Little Book of Rust Macros - Book
https://veykril.github.io/tlborm/introduction.html -
Writing Interpreters in Rust: a Guide - Book
https://rust-hosted-langs.github.io/book/introduction.html -
Video - Cheaply writing a fast interpreter - Neil Mitchell
https://www.youtube.com/watch?v=V8dnIw3amLA
github
https://github.com/ndmitchell/interpret -
Make A Language
A series about making a programming language called Eldiro using the Rust programming language.
https://arzg.github.io/lang/ -
Engineering Rust Web Applications - Book
https://erwabook.com/ -
Programming Rust: Fast, Safe Systems Development 2nd Ed
by Jim Blandy, Jason Orendorff -
Rust for Rustaceans: Idiomatic Programming for Experienced Developers
by Jon Gjengset -
Refactoring to Rust
by Lily Mara -
Practical System Programming for Rust Developers
Build fast and secure software for Linux/Unix systems with the help of practical examples
by Prabhu Eshwarla -
Hands-On Concurrency with Rust: Confidently build memory-safe, parallel, and efficient software in Rust
by Brian L. Troutwine -
GDB: The GNU Project Debugger
https://www.gnu.org/software/gdb/documentation/ -
The LLDB Debugger
https://lldb.llvm.org/ -
Valgrind User Manual
https://valgrind.org/docs/manual/manual.html -
The perf Linux profiler - Examples of use
https://www.brendangregg.com/perf.html -
QuickCheck - QuickCheck is a way to do property based testing using randomly generated input.
https://github.com/BurntSushi/quickcheck -
American Fuzzy Lop - A good fuzzer
https://lcamtuf.coredump.cx/afl/ -
Criterion rs - Statistics-driven Microbenchmarking in Rust
https://github.com/bheisler/criterion.rs -
The Complete Rust Programming Reference Guide: Design, develop, and deploy effective software systems using the advanced constructs of Rust
by Rahul Sharma, Vesa Kaihlavirta -
Creative Projects for Rust Programmers: Build exciting projects on domains such as web apps, WebAssembly, games, and parsing
by Carlo Milanesi -
Rust High Performance: Learn to skyrocket the performance of your Rust applications
by Iban Eguia Moraza -
Writing an OS in Rust Philipp Oppermann's blog
https://os.phil-opp.com/ -
The Rust Unstable Book
https://doc.rust-lang.org/beta/unstable-book/
Text Processing in Rust
-
Text Processing in Rust
by Mihalis Tsoukalos
https://www.linuxjournal.com/content/text-processing-rust -
Working with strings in Rust - fasterThanLime Blog
https://fasterthanli.me/articles/working-with-strings-in-rust -
String continuations
The backslash, the newline and the starting spaces will disappear.
println!(
"... the {p}, by the {p}, for the {p}, \
will never fall.",
p = "people"
);
Will print:
"... the people, by the people, for the people, will never fall."
- For ASCII Strings (value lower then 127) non UTF-8 strings, one can process much faster the string if it is converted to bytes and then compared to bytes.
let my_str = "Hello!".to_string();
for c in my_str.chars() {
if c == 'l' {
// Do something!
}
}
// A faster implementation for ASCII characters would be.
let my_str_2 = "Hello!".to_string();
for b in my_str.bytes() {
if b == b'l' {
// Do something!
}
}
// There is also a slice of bytes.
let my_str_3 = "Hello!".to_string();
let my_str_as_bytes_slice = my_str_3.as_bytes();
if my_str_as_bytes_slice[2] == b'l' {
// Do something!
}
-
Kibi - A text editor in ≤1024 lines of code, written in Rust
https://github.com/ilai-deutel/kibi -
Rust substring processing
My section below on it.
How Rust maps to memory and lifetimes annotations in Rust
-
Video - Visualizing memory layout of Rust's data types - Sreekanth
Incredible video!
https://www.youtube.com/watch?v=rDoqT-a6UFg -
Video - Understanding Rust Lifetimes - Ryan Levick
https://www.youtube.com/watch?v=MSi3E5Z8oRw -
Video - Crust of Rust: Lifetime Annotations - Jon Gjengset
https://www.youtube.com/watch?v=rAl-9HwD858 -
Implementing a HashMap in Rust.
Video - Live-coding a linked hash map in Rust - Jon Gjengset
https://www.youtube.com/watch?v=k6xR2kf9hlA
How to deal with Circular References and Ownership
- Rust data structures with circular references
https://eli.thegreenplace.net/2021/rust-data-structures-with-circular-references/
GitHub code
https://github.com/eliben/code-for-blog/tree/master/2021/rust-bst
The previous link demonstrated 3 ways to attack the problem:
1- Defer borrow checking to run-time, by using a reference-counted pointer (std::rc::Rc
) to a std::cell:RefCell
.
2- Centralize the ownership (e.g. all nodes are owned by a vector of nodes in the Tree), and then references become handles (indices into the a vector).
3- Use raw pointers and unsafe blocks to go around the rules of safe Rust.
Polymorphism in Rust
-
Three Kinds of Polymorphism in Rust - Brandon Smith
https://www.brandons.me/blog/polymorphism-in-rust -
Polymorphism in Rust - Matt Oswalt
https://oswalt.dev/2021/06/polymorphism-in-rust/ -
Anti-pattern - Deref polymorphism
https://rust-unofficial.github.io/patterns/anti_patterns/deref.html
Rust Testing and TDD - Test Driven Development
- Video - Rust Testing and TDD - An Intro to Testing and Test Driven Development
https://www.youtube.com/watch?v=2vBQFIWl36k
Systems programming in Rust
-
Crate libc - Raw FFI bindings to platforms system libraries
https://crates.io/crates/libc -
Crate nix - Rust friendly bindings to _nix APIs
https://crates.io/crates/nix -
How to use ptrace() system call to trace system calls and CPU registers on a external program,
by running it as a child process or by attachment to a running process.
Blog post - Implementing strace in Rust - jakobwaibel
https://jakobwaibel.com/2022/06/06/ptrace/ -
How to use ptrace() system call to implement a debugger.
System programming in Rust, take 2 - carstein
https://carstein.github.io/2022/05/29/rust-system-programming-2.html
Background in systems programming
-
How to learn modern Linux
https://github.com/joaocarvalhoopen/How_to_learn_modern_Linux -
Safe Systems Programming in Rust
By Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, Derek Dreyer
https://cacm.acm.org/magazines/2021/4/251364-safe-systems-programming-in-rust/fulltext -
The Linux Command Line, 2nd Edition: A Complete Introduction Illustrated Edition
by William Shotts -
How Linux Works, 3rd Edition: What Every Superuser Should Know 3rd Edition
by Brian Ward -
Operating Systems: Three Easy Pieces
Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
http://pages.cs.wisc.edu/~remzi/OSTEP/ -
The Linux Programming Interface: A Linux and UNIX System Programming Handbook
by Michael Kerrisk
Note: Read this book from cover to cover! -
System Programming Vol I and Vol II
by Jin-Jwei Chen
Note: Read this book from cover to cover! -
Dive into Systems
by Suzanne J. Matthews, Tia Newhall, Kevin C. Webb
https://diveintosystems.org/
Note: Read this book from cover to cover! -
Linux Device Drivers, 3th Edition
https://lwn.net/Kernel/LDD3/ -
Linux Driver Development for Embedded Processors - 2th Edition: Learn to develop Linux embedded drivers with kernel 4.9 LTS
by Alberto Liberal de los Ríos -
Computer Systems: A Programmer's Perspective 3rd Edition
by Randal Bryant, David O'Hallaron -
Computer Networking: A Top-Down Approach
by James Kurose -
The Illustrated Network: How TCP/IP Works in a Modern Network 2nd Edition
by Walter Goralski -
C Programming: A Modern Approach, 2nd Edition
by K. N. King -
Effective C - An Introduction to Professional C Programming
by Robert C. Seacord -
CERT C Coding Standard - The 98 Rules for Developing Safe, Reliable, and Secure Systems 2nd Edition
by Robert C. Seacord (Author)** -
Extreme C: Taking you to the limit in Concurrency, OOP, and the most advanced capabilities of C
by Kamran Amini -
Programming - Principles and Practice Using C++ 2nd Edition, C++ 14
by Bjarne Stroustrup -
C++ Crash Course: A Fast-Paced Introduction, C++ 17
by Josh Lospinoso
Writing Compilers in Rust
-
Crafting Interpreters
by Robert Nystrom
The book license is Creative Commons.
https://craftinginterpreters.com/
Lox Implementations
https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations
Crafting Interpreters in Rust - tdp2110
https://github.com/tdp2110/crafting-interpreters-rs
Crafting A Lox Interpreter In Rust, Part 1 - Diego Freijo
https://www.diegofreijo.com/blog/rlox-vm-a-lox-interpreter-in-rust-part-1/ -
Video Play List - Crafting Interpreters - Uncle Scientist
https://www.youtube.com/playlist?list=PLib6-zlkjfXluRjBgK8grQH2IUSZjn-YN -
LISP interpreter in Rust
https://vishpat.github.io/lisp-rs/ -
Writing An Interpreter In Go
by Thorsten Ball -
Writing A Compiler In Go
by Thorsten Ball -
Compilers: Principles, Techniques, and Tools
by Alfred Aho, Monica Lam, Ravi Sethi
Contributing to the Rust Compiler rustc
-
Video - RustConf 2021 - Hacking rustc: Contributing to the Compiler by Esteban Kuber
https://www.youtube.com/watch?v=9H9SO2u6Q20 -
Video - rustc - A talk by Mark Mansi about the Rust programming language and compiler
https://www.youtube.com/watch?v=68U8ZZ1EnEQ -
Video - Hacking on rustc - Negative literals in indexing expressions
https://www.youtube.com/watch?v=OGihuce8rl8 -
Rust Lang - Compiler Team
https://rust-lang.github.io/compiler-team/ -
The Rust Compiler - rustc
https://github.com/rust-lang/rust -
rustc API docs - rustdoc documentation for the compiler
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ -
Zulip Chat - rust-lang
https://rust-lang.zulipchat.com/ -
Forum Rust Internals
https://internals.rust-lang.org/ -
Guide to Rustc Development - Book
https://rustc-dev-guide.rust-lang.org/ -
Video Play List - rustc lecture series
https://www.youtube.com/playlist?list=PL85XCvVPmGQhOL-J2Ng7qlPvDVOwYpGTN
WebAssembly in Rust - WASM
-
Rust and WebAssembly - Book
https://rustwasm.github.io/docs/book/ -
Write Your First WASM Module using Rust
https://www.youtube.com/watch?v=nW71Mlbmxt8 -
Getting Started with WebAssembly and Rust: A First Look
https://www.youtube.com/watch?v=YHJjmsw_Sx0 -
Crate wasm-bindgen
Facilitating high-level interactions between Wasm modules and JavaScript.
GitHub
https://github.com/rustwasm/wasm-bindgen
The wasm-bindgen guide - Book
https://rustwasm.github.io/docs/wasm-bindgen/ -
Project WASM Fourier
Example of browser audio microphone data passed to Rust WASM module.
Note: Really cool example to study and for example do APP's with audio processing on Rust.
https://github.com/linanova/wasm-fourier -
Video - Rust + Yew + WASM + Canvas - Vers Binarii
https://www.youtube.com/watch?v=7Smco8araSo
WebFrameworks in Rust - Similar to React Angular or Vue
-
Crate Yew.rs - A framework similar to React, Angular or Vue,
but without Javascript, the development is all made in Rust.
https://yew.rs/ -
Video Playlist - Introduction to Yew.rs Course - Brooks Builds
https://www.youtube.com/playlist?list=PLrmY5pVcnuE_R5qJ0o30eGw77bWmnrUtL
Python extended with Rust and running a Python interpreter inside Rust
-
PyO3 - GitHub
https://github.com/PyO3/pyo3 -
The PyO3 user guide - Book
https://pyo3.rs/master/ -
Python Extensions in Pure Rust with PyO3
https://depth-first.com/articles/2020/08/10/python-extensions-in-pure-rust-with-pyo3/ -
RustPython - A Python-3 interpreter written in Rust
https://github.com/RustPython/RustPython
Rust with inline Python
In a program made in Rust, use a macro to insert inline Python
and move easily data (variables) between the two.
// Example_1
use inline_python::python;
fn main() {
let who = "world";
let n = 5;
python! {
for i in range('n):
print(i, "Hello", 'who)
print("Goodbye")
}
}
// Example_2
// Creates the data in Rust and plots the plot with inline Python with the lib matplotlib.
use inline_python::python;
fn main() {
let data = vec![(4, 3), (2, 8), (3, 1), (4, 0)];
python! {
import matplotlib.pyplot as plt
plt.plot('data)
plt.show()
}
}
- Crate inline-python
Inline Python code directly in your Rust code
https://crates.io/crates/inline-python
The inner workings and all the development steps of this project are beautifully explained, in detail, on this sequence of blog posts.
-
Writing Python inside your Rust code - Part 1 - Mara's Blog
https://blog.m-ou.se/writing-python-inside-rust-1/ -
Writing Python inside your Rust code - Part 1A - Mara's Blog
https://blog.m-ou.se/writing-python-inside-rust-1a/ -
Writing Python inside your Rust code - Part 2 - Mara's Blog
https://blog.m-ou.se/writing-python-inside-rust-2/ -
Writing Python inside your Rust code - Part 3 - Mara's Blog
https://blog.m-ou.se/writing-python-inside-rust-3/ -
Writing Python inside your Rust code - Part 4 - Mara's Blog
https://blog.m-ou.se/writing-python-inside-rust-4/
Rust on or for the Raspberry Pi
- There are two modes of using Rust with the Raspberry Pi.
The first one is installing Rust development tools on the Raspberry Pi it self, and the second one is installing on the PC and making cross-compilation to generate a executable that runs on the Raspberry Pi.
Developing on the Raspberry Pi and running Rust programs on the Raspberry Pi
- How to Get Started With Rust on Raspberry Pi
https://www.muo.com/tag/getting-started-rust-raspberry-pi/
Developing on the PC and cross-compiling to run Rust programs on the Raspberry Pi
-
Cross Compiling Rust for the Raspberry Pi
It also explains a method to automatically coping the file to the Raspberry Pi after compilation.
https://chacin.dev/blog/cross-compiling-rust-for-the-raspberry-pi/ -
Cross compiling Rust for Raspberry Pi
https://dev.to/h_ajsf/cross-compiling-rust-for-raspberry-pi-4iai
Raspberry Pi Bare Metal
-
Github - Zoltan Baldaszti - Bare metal Raspberry Pi 3 tutorials
https://github.com/bztsrc/raspi3-tutorial/ -
Writing a bare metal operating system for Raspberry Pi 4
https://www.rpi4os.com/ -
Video Playlist - Low Level Devel - Raspberry Pi Bare Metal
https://www.youtube.com/playlist?list=PLVxiWMqQvhg9FCteL7I0aohj1_YiUx1x8 -
Video baremetal Rust Runs on everything, Including the Raspberry Pi - Embedded Rust Tutorial
by Low Level Learning
https://www.youtube.com/watch?v=jZT8APrzvc4 -
Github - Operating System development tutorials in Rust on the Raspberry Pi
https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials
Embedded Rust
-
An Overview of the Embedded Rust Ecosystem - end 2020
https://www.youtube.com/watch?v=vLYit_HHPaY -
Awesome embedded rust - Github
Everything you need to know including drivers to connect external devices to the micro-controller.
https://github.com/rust-embedded/awesome-embedded-rust -
The Embedded Working Group Newsletter or Blog
https://rust-embedded.github.io/blog/ -
Discovery Book
Good starting point for MicroBit and STM32
https://docs.rust-embedded.org/discovery/ -
PlayList - Embedded Rust course - JaJakub - 2022
https://www.youtube.com/playlist?list=PLL2SCPK5xSRWBPj-nKOVYIhxRw7C4kYeI -
Live streams with a good example of developing with Embedded Rust in STM32 BluePill
Embedded Rust - Vers Binarii
https://www.youtube.com/playlist?list=PLP_X41VhYn5X6Wwjnm0bRwI3n2pdaszxU -
Embedded Hardware Development with Rust - 2018
https://www.youtube.com/watch?v=g25xsK3HKkE -
Embedded Programming is Getting Rust-y - end of 2021
Embedded Computing Design
https://www.youtube.com/watch?v=sOTx5324nKI -
The Embedded Rust Book
Second fantastic book to read
Generic for any type of chip brand.
https://docs.rust-embedded.org/book/ -
Workbook for Embedded Workshops - Book
Using the Nordic nRF52840 Development Kit.
https://embedded-trainings.ferrous-systems.com/ -
The Embedonomicon Book
Deep dive into the inner workings.
https://docs.rust-embedded.org/embedonomicon/ -
Video - How can we write the best device driver?
https://www.youtube.com/watch?v=z9z74VpqO9A -
Video - RTIC - Real Time Interrupt driven Concurrency
RTIC is a RTOS - Real Time Operating System.
https://www.youtube.com/watch?v=saNdh0m_qHc -
RTIC Book
Real-Time Interrupt-driven Concurrency.
A very efficient preemptive multitasking framework that supports task prioritization and dead lock free execution.
https://rtic.rs/1.0/book/en/ -
Github - rtic-rs - cortex-m-rtic
https://github.com/rtic-rs/cortex-m-rtic -
Video - Grepit about the Rust RTIC framework
https://www.youtube.com/watch?v=sSJ-Md8nwIM -
Good RTIC project example
Rust firmware for IR thermometer in STM32 with LCD - geomatsi - rust-ir-thermo
https://github.com/geomatsi/rust-ir-thermo -
Video - Bare Metal Audio Programming With Rust - Antoine van Gelder - ADC20
https://www.youtube.com/watch?v=udlK1LQ3f3g
Slides
https://flowdsp.io/talks/talk-adc20/#1 -
Video - Building a simple logic analyser in Rust
Rust Linz, September 2020 - Roland Ruckerbauer - Embedded Rust
Board used stm32 compatible bluepill.
https://www.youtube.com/watch?v=xY342ACNXFg
Slides
https://github.com/ruabmbua/rlogic/blob/master/presentation.pdf
Github - ruabmbua - rlogic
https://github.com/ruabmbua/rlogic
Embedded Rust crates and code size optimization
- Crate heapless
https://github.com/japaric/heapless
Arc - Thread-safe reference-counting pointer backed by a memory pool
BinaryHeap - Priority queue
IndexMap - Hash table
IndexSet - Hash set
LinearMap
Pool - Lock-free memory pool
String
Vec
mpmc::Q* - Multiple producer multiple consumer lock-free queue
spsc::Queue - Single producer single consumer lock-free queue
-
Crate ufmt
A (6-40x) smaller, (2-9x) faster and panic-free alternative to core::fmt
https://github.com/japaric/ufmt -
LCD 16x2 - Crate hd44780-driver
Implementation of the embedded-hal traits for the HD44780, 16x1, 16x2 and 16x4.
https://github.com/JohnDoneth/hd44780-driver -
Crate Embedded graphics
It's a 2D graphics library that is focused on memory constrained embedded devices.
https://github.com/embedded-graphics/embedded-graphics -
Crate flip-link
Adds zero-cost stack overflow protection to your embedded programs.
https://github.com/knurling-rs/flip-link/ -
Crate defmt
defmt ("de format", short for "deferred formatting") is a highly efficient logging framework that targets resource-constrained devices, like micro-controllers.
https://github.com/knurling-rs/defmt/ -
TOML compilation flag options to generate smaller code size
....
[profile.release.package."*"]
opt-level = "z"
[profile.release]
codegen-units = 1
debug = true
opt-level = "z"
Embedded Rust with STM32 BluePill - STM32F103
- STM32 BluePill in Rust - Project template and lot's of info
This is the project template I use in my BluePill projects.
https://github.com/joaocarvalhoopen/stm32_bluepill_in_rust__Template
Embedded Rust with Raspberry Pi Pico - 4 dollars board
-
All relevant Info and a starting project Template.
Where I have put all the info that I consider to be relevant for Pico development in Rust.
Raspberry Pi Pico in Rust Proj Template with RTIC USB-Serial and UF2
https://github.com/joaocarvalhoopen/Raspberry_Pi_Pico_in_Rust__Proj_Template_with_RTIC_USB-Serial_UF2 -
Raspberry Pi Pico - rp-HAL
https://github.com/rp-rs/rp-hal
rp2040-hal - Examples
https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal/examples
Examples for the board rp-pico.
https://github.com/rp-rs/rp-hal/tree/main/boards/rp-pico
Documentation
https://docs.rs/rp2040-hal/latest/rp2040_hal/ -
Site - rp2040 - Chip documentation
https://www.raspberrypi.com/documentation/microcontrollers/ -
Getting Started with Rust on a Raspberry Pi Pico - Part 1
https://reltech.substack.com/p/getting-started-with-rust-on-a-raspberry -
Getting Started with Rust on a Raspberry Pi Pico - Part 2
https://reltech.substack.com/p/getting-started-with-raspberry-pi -
Getting Started with Rust on a Raspberry Pi Pico - Part 3
https://reltech.substack.com/p/getting-started-with-rust-on-a-raspberry-a88 -
Oleg Eterevsky comment on the previous page - Slightly simpler setup. Instead of using a separate controller for handling the debug, he have just set up debug logging via USB serial port. This requires a bit more boilerplate (handling the USB interrupt and such), but is much simpler from the hardware perspective: you need to just plug in a single Pico board in your USB, flash it and you can immediately see the debug output.
USB_Serial - repo
https://github.com/eterevsky/rp2040-blink -
Crate usb-device - Experimental device-side USB stack for embedded devices.
https://crates.io/crates/usb-device -
Way to easily Reboot the Pico to USB-PEN mode to program it
You can have a easy reboot without needing to disconnecting and while pressing the boot button reconnecting the cable.
Just add a switch from pin RUN to GND and while pressing the Boot Button press the Run Button and release the Run switch and them the Boot Button. It will enter the USB-PEN mode, that allows you to program by just coping the Rust or C binary from the PC to the Raspberry Pico micro-controller.
See official documentation for details. -
PlayList - Rust Pico - Low Level Learning
https://www.youtube.com/playlist?list=PLc7W4b0WHTAUAEAguiqpNa5H0QqXJIJI6 -
Play List - Raspberry Pi Pico in C - Low Level Learning
https://www.youtube.com/playlist?list=PLc7W4b0WHTAV6EYRVayb9c9dEsq-NeXAt -
PlayList - Intro to Raspberry Pi Pico and RP2040 - Digi-Key
C/C++ and MicroPython
https://www.youtube.com/playlist?list=PLEBQazB0HUyQO6rJxKr2umPCgmfAU-cqR -
In-depth: Raspberry Pi Pico's PIO - programmable IO - stacksmashing
https://www.youtube.com/watch?v=yYnQYF_Xa8g -
Site - Raspberry Pi Pico
https://www.raspberrypi.com/products/raspberry-pi-pico/ -
Site - Getting started with Raspberry Pi Pico
https://projects.raspberrypi.org/en/projects/getting-started-with-the-pico/0 -
Book - Get Started with MicroPython on Raspberry Pi Pico
https://hackspace.raspberrypi.com/books/micropython-pico -
Book - Adafruit - Getting Started with Raspberry Pi Pico and CircuitPython
https://cdn-learn.adafruit.com/downloads/pdf/getting-started-with-raspberry-pi-pico-circuitpython.pdf -
Video - The Raspberry Pi Pico Review - $4 ARM Microcontroller
https://www.youtube.com/watch?v=dUCgYXF01Do -
Video - Raspberry Pi Pico VGA video output using only resistors
https://www.youtube.com/watch?v=RmPWcsvGSyk
Embedded Rust with ESP32
-
esp-rs - Rust on ESP-IDF "Hello, World" template
https://github.com/esp-rs/esp-idf-template -
Video - Embedded Rust: Wifi and I2C on a ESP32-C3 - Andrei Litvin
https://www.youtube.com/watch?v=CXm7NdBBegk
GitHub andy31415 - rust-esp32-c3-demos
https://github.com/andy31415/rust-esp32-c3-demos/tree/oled_wifi -
ivmarkov - rust-esp32-std-demo
A complex demo of ESP32 in Rust
https://github.com/ivmarkov/rust-esp32-std-demo
Links
-
Rust site
A language empowering everyone to build reliable and efficient software.
https://www.rust-lang.org/ -
Song - Rust 2021 Edition
https://www.youtube.com/watch?v=q0aNduqb2Ro -
Crate.io - The Rust community’s crate registry
https://crates.io/ -
Rust weekly news letter
https://this-week-in-rust.org/ -
The Little Book of Rust Books
https://lborb.github.io/book/title-page.html -
Awesome-rust
https://github.com/rust-unofficial/awesome-rust -
Awesome-embedded-rust
https://github.com/rust-embedded/awesome-embedded-rust -
Rust Analyzer - User manual and short cut keys
https://rust-analyzer.github.io/manual.html -
Jon Gjengset - Rust in depth Youtube channel.
https://www.youtube.com/c/JonGjengset -
Tokio
Tokio is an asynchronous runtime (async and await) for the Rust programming language. It provides the building blocks needed for writing network applications. It gives the flexibility to target a wide range of systems, from large servers with dozens of cores to small embedded devices.
See the tutorials.
https://tokio.rs/ -
Best async and await introduction video.
Video - Crust of Rust: async e await - Jon Gjengset
https://www.youtube.com/watch?v=ThjvMReOXYM -
Video - Creating a Chat Server with async Rust and Tokio – Lily Mara
https://www.youtube.com/watch?v=Iapc-qGTEBQ -
Tracing - Log tracing platform
https://github.com/tokio-rs/tracing -
Actix Web
Web Framework that's blazing fast, secure, asynchronous runs over Tokio and is "similar" to Flask of Python.
Can process 650.000 request per second.
https://actix.rs/ -
Rocket
Web Framework that's fast, secure and more "similar" to Django of Python.
https://rocket.rs/ -
Serde
Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.
https://serde.rs/
https://crates.io/crates/serde -
BindGen
Automatically generates Rust FFI bindings to C and C++ libraries.
https://crates.io/crates/bindgen
Tutorial guide.
https://rust-lang.github.io/rust-bindgen/ -
Hacking rustc: Contributing to the Compiler by Esteban Kuber - RustConf 2021
https://www.youtube.com/watch?v=9H9SO2u6Q20
Rust Foundation
-
Video - What Is Rust Foundation?
https://www.youtube.com/watch?v=AI4lPN0BqGc -
Site - Rust Foundation
https://foundation.rust-lang.org/
Rust Blogs
-
pretzelhammer's Rust blog
https://github.com/pretzelhammer/rust-blog-
RESTful API in Sync & Async Rust - pretzelhammer
https://github.com/pretzelhammer/rust-blog/blob/master/posts/restful-api-in-sync-and-async-rust.md -
Common Rust Lifetime Misconceptions - pretzelhammer
https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md -
Tour of Rust's Standard Library Traits - pretzelhammer
https://github.com/pretzelhammer/rust-blog/blob/master/posts/tour-of-rusts-standard-library-traits.md -
Sizedness in Rust – pretzelhammer
https://github.com/pretzelhammer/rust-blog/blob/master/posts/sizedness-in-rust.md
-
-
fasterThanLime Blog - Amos Wenger
https://fasterthanli.me
Rust Youtube Channels
-
Channel Rust
https://www.youtube.com/c/RustVideos/videos -
Channel Rust Foundation
https://www.youtube.com/channel/UC0jzvznwtnsdXYIp415oC9g/videos -
Channel fasterthanlime - Amos Wegner
https://www.youtube.com/c/fasterthanlime/videos -
Channel Jon Gjengset - Rust in depth Youtube channel.
https://www.youtube.com/c/JonGjengset/videos -
Channel Tensor Programming - Intro to Rust
https://www.youtube.com/playlist?list=PLJbE2Yu2zumDF6BX6_RdPisRVHgzV02NW -
Channel Tensor Programming - Rust Projects
https://www.youtube.com/playlist?list=PLJbE2Yu2zumDD5vy2BuSHvFZU0a6RDmgb -
Channel Let's Get Rusty
https://www.youtube.com/c/LetsGetRusty/videos -
Channel Uncle Scientist
https://www.youtube.com/channel/UClnm0enwPt9iPWGZ5uh3Bfw/videos -
Channel Ryan Levick
https://www.youtube.com/c/RyanLevicksVideos/videos -
Channel Tantan
https://www.youtube.com/c/Tantandev/videos -
Channel Crazcalm's Tech Stack
https://www.youtube.com/c/CrazcalmsTechStack/videos -
Channel Ferrous Systems GmbH
Embedded Rust
https://www.youtube.com/c/FerrousSystemsGmbH/videos -
Channel JaJakub
Embedded Rust
https://www.youtube.com/c/JaJakubYT/videos -
Channel Vers Binarii
Embedded Rust
https://www.youtube.com/channel/UCgLxnJi8BU476a3uZO29H4w/videos
GUI programming in Rust
-
GTK4 - Unlocking the GNOME stack for Rust
https://gtk-rs.org/ -
Book - GUI development with Rust and GTK 4
https://gtk-rs.org/gtk4-rs/stable/latest/book/ -
Relm4 for GTK4
https://github.com/AaronErhardt/relm4 -
Speedrunning GUI development in Rust
Hint: 1.2 seconds compilation technic.
https://aaronerhardt.github.io/blog/posts/gui_speedrun/ -
egui: an easy-to-use GUI in pure Rust
Normal desktop GUI and WebAssembly written entirely in Rust, immediate mode.
https://github.com/emilk/egui -
eGUI - Web Demo
https://emilk.github.io/egui/index.html -
eframe - It's the official framework library for writing apps using egui
https://github.com/emilk/egui/tree/master/eframe -
egui - 7a. Building a GUI app in Rust - Part A - creativcoder
https://www.youtube.com/watch?v=NtUkr_z7l84 -
egui - 7b. Building a GUI app in Rust - Part B - creativcoder
https://www.youtube.com/watch?v=SvFPdgGwzTQ -
egui - 8. Building a web app in Rust - WASM - creativcoder
https://www.youtube.com/watch?v=4MKcqR9z8AU -
Crate confy
To maintain the state fo the APP in a config file. Serializes and deserializes automatically with Serde.
https://github.com/rust-cli/confy -
Crate tracing
https://github.com/tokio-rs/tracing -
pix_engine
It's a cross-platform graphics & UI library for simple games, visualizations, digital art, and graphics applications. A kind of more simple Processing or p5.js but for Rust. Has a good collection of examples.
https://github.com/lukexor/pix-engine
Audio in Rust
-
RustAudio
Free and useful Audio, DSP and music libraries written in Rust.
https://github.com/RustAudio -
CPAL - Cross-Platform Audio Library
Low-level library for audio input and output in pure Rust.
Works aldo in WASM.
https://github.com/RustAudio/cpal -
Rodio - Audio playback library
MP3, WAV, Vorbis, Flac, MP4 and AAC.
https://github.com/RustAudio/rodio -
dasp - Digital Audio Signal Processing in Rust
https://github.com/RustAudio/dasp -
rust-portaudio - PortAudio bindings and wrappers for Rust.
https://github.com/RustAudio/rust-portaudio
Faster Compilation - Linker times in Linux and Unix ELF
mold is optimized for Linux, zld only works on macOS. For production use, lld might be the most mature option.
mold is a high-performance drop-in replacement for existing Unix linkers. It is several times faster than LLVM lld linker
In the context of building a Relm4 for GTK-4 GUI application:
"With mold I was able to reduce my incremental compile times by factor 7 to only about 1.2 second. With this, it’s really fun to play with the code of the UI as you can see the result of your changes almost immediately." by the author of Relm4
// After installing mold, all you need to do is add the
// prefix mold -run to the command you want to run.
// Most likely this will be:
mold -run cargo run
- Tips for Faster Rust Compile Times
https://endler.dev/2020/rust-compile-times/
Machine Learning for Rust
-
Taking ML to production with Rust: a 25x speedup
https://www.lpalmieri.com/posts/2019-12-01-taking-ml-to-production-with-rust-a-25x-speedup/ -
Machine learning in Rust using Linfa
https://blog.logrocket.com/machine-learning-in-rust-using-linfa/ -
Crate Linfa
linfa aims to provide a comprehensive toolkit to build Machine Learning applications with Rust.
Kin in spirit to Python's scikit-learn, it focuses on common preprocessing tasks and classical ML algorithms for your everyday ML tasks.
https://crates.io/crates/linfa
https://github.com/rust-ml/linfa -
Crate tch-rs
Rust wrappers for the PyTorch C++ api (libtorch).
https://crates.io/crates/tch
https://docs.rs/tch -
Crate Rust TensorFlow
TensorFlow Rust provides idiomatic Rust language bindings for TensorFlow.
https://crates.io/crates/tensorflow
https://github.com/tensorflow/rust -
Crate rust-xgboost
Rust bindings for the XGBoost gradient boosting library.
https://crates.io/crates/xgboost
Rust VSCode plugins
-
rust-analyzer
Code analyzer while editing
https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer
For better warnings in the same user interface, go into the VSCode settings > Rust Analyzer > Check On Save: Command and setting “clippy” instead of “check”. -
Better TOML
.toml syntax hilight.
https://marketplace.visualstudio.com/items?itemName=bungcip.better-toml -
Error Lens
Better positioning of error messages in editor.
https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens -
CodeLLDB - Vadim Chugunov
Debugger plugin for Rust.
https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb -
Code Spell Checker
https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker -
Markdown All in One
https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
Rust Debugger
-
How to Debug Rust with Visual Studio Code
https://www.forrestthewoods.com/blog/how-to-debug-rust-with-visual-studio-code/ -
Debugging Rust with VS Code
https://dev.to/rogertorres/debugging-rust-with-vs-code-11dj -
CodeLLDB - Vadim Chugunov
Plugin for VS Code
https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb
Rust Error Handling
To define good error types that encapsulate other errors. In the case where you need to return from a function, multiple incompatible types, and you don't want to manually write conversion functions that implement the trait std::convert::From< > .
-
Crate Anyhow
Use Anyhow if you don't care what error type your functions return, you just want it to be easy. This is common in application code.
https://crates.io/crates/anyhow -
Crate thiserror
Use thiserror if you are a library that wants to design your own dedicated error type(s) so that on failures the caller gets exactly the information that you choose.
https://crates.io/crates/thiserror
Tips and Tricks
-
12 Rust Tips and Tricks you might not know yet - Federico Terzi
https://federicoterzi.com/blog/12-rust-tips-and-tricks-you-might-not-know-yet/ -
sccache - Shared Compilation Cache
sccache includes support for caching the compilation of C/C++ code, Rust, as well as NVIDIA's CUDA using nvcc. Avoiding compilation when possible.
https://github.com/mozilla/sccache
GC for Rust - Garbage Collector
“Cases where one needs to maintain a complicated, dynamic graph “(with cycles)” are where a GC becomes useful. Similarly, if one is writing an interpreter for a GCd language, having a GC in Rust would simplify things a lot.”
-
Designing a GC in Rust
https://manishearth.github.io/blog/2015/09/01/designing-a-gc-in-rust/ -
Crate rust-gc
https://crates.io/crates/gc
Examples
https://github.com/Manishearth/rust-gc/tree/master/gc/tests
Programming Parallel computers - Optimization guide C Plus Plus and Rust
-
Programming Parallel Computers - In depth lectures notes
https://ppc.cs.aalto.fi/ -
Comparing Parallel Rust and C++
https://parallel-rust-cpp.github.io/ -
Crossbeam - Tools for concurrent programming
https://crates.io/crates/crossbeam
Crossbeam - Learning Resources
https://github.com/crossbeam-rs/rfcs/wiki -
Rayon - It is a data-parallelism library for Rust
https://crates.io/crates/rayon
Video - Rayon: Data Parallelism for Fun and Profit — Nicholas Matsakis
https://www.youtube.com/watch?v=gof_OEv71Aw
Rayon: data parallelism in Rust
https://smallcultfollowing.com/babysteps/blog/2015/12/18/rayon-data-parallelism-in-rust/
Rayon docs
https://docs.rs/rayon/latest/rayon/ -
dpc-pariter - Parallel iterator processing
https://crates.io/crates/dpc-pariter
Adding parallelism to your Rust iterators with dpc-pariter
https://dpc.pw/adding-parallelism-to-your-rust-iterators -
perf Examples
See also the lecture.
https://www.brendangregg.com/perf.html -
perf: Linux profiling with performance counters
https://perf.wiki.kernel.org/index.php/Main_Page -
Systems Performance Enterprise and the Cloud 2nd Ed
by Brendan Gregg
To install Perf on your Linux system you can do a simple package installation like apt-get if you are on a debian, then execute perf and it will tell you the package that you will have to install that is specific for your Linux kernel version. If your distribution automatically updates your kernel, you will need to download a new and correct version for your new kernel, and install it with your system package manager, ex: apt-get.
In the Rust .toml file add the 2 following lines, to add the debug symbols table to the Rust executable program file, compiled with --release
flag:
[profile.release]
debug = true
To run Perf profiling on your Rust executable program. After that you can also use flamegraph.
# Temporarily activate this flag perf_event_paranoid.
> echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
# Record the executable program profiling data in a .data file.
> perf record -F99 --call-graph dwarf
# To see the report use with Up/Down arrow keys, with "+"
# and with "a" to see the annotated assembly code with the Rust
# code correspondent code. The report will include the % of time in
# inside the function and in each group of assembly instructions.
# Press "tab" key in annotation mode to jump between hot spots.
> perf report
The Perf profiler has many command use the stat command to get the IPC – Instruction Per Clock Cycle, it's an average.
To know how much peak memory your executable program uses do:
> /usr/bin/time -v
Note: There are 2 "time" executables and this is not the bash default time program. That's why you have to write the full path /usr/bin/time
to execute it.
-
The Rust Performance Book
https://nnethercote.github.io/perf-book/title-page.html -
Guide to Optimization
Achieving warp speed with Rust
https://gist.github.com/jFransham/369a86eff00e5f280ed25121454acec1
Cheap tricks for high-performance Rust
https://deterministic.space/high-performance-rust.html
Video - Optimizing Rust - Rust Oslo 2021-11-11 - Lily Mara
https://www.youtube.com/watch?v=LQ2nIhj45vE
Optimization - Making Rust Code Go Brrrr
https://aspenuwu.me/posts/rust-optimization.html
Profile Guided Optimization
https://doc.rust-lang.org/rustc/profile-guided-optimization.html
Optimizations: the speed size tradeoff
https://rust-embedded.github.io/book/unsorted/speed-vs-size.html
Rust Optimization - Compilation modes and flags
The best way to optimize your code is to choose the right algorithm and the right data structures.
-
How to become dangerous in Algorithms
https://github.com/joaocarvalhoopen/How_to_become_dangerous_in_algorithms -
The Algorithms - Rust
https://github.com/TheAlgorithms/Rust -
The Algorithms - Python
For a more complete list of implementations of algorithms
https://github.com/TheAlgorithms/Python/blob/master/DIRECTORY.md
You can also apply several coding techniques that come from the underling knowledge of how the rust transforms your code structures in memory (stack and heap) and how they are executed, for example avoiding allocation, avoiding cloning large things that aren’t basic types and that are by nature cloned. (More info bellow.) You can do profiling to guide you through optimization, identifying the hot-spots to pin point you to the exact code your program spends that 90% of his time. And to allow you to see where you can shave it in the number of instructions that are executed at the same time and to increase your IPC – Instructions Per Clock cycle of your superscaller CPU. And then you can also mess around with compilation flags like the following, see https://nnethercote.github.io/perf-book/build-configuration.html :
-
rustc book - rustc is the Rust compiler
https://doc.rust-lang.org/rustc/ -
Add debug symbols table to the release build for profiling. In
Cargo.toml
.
[profile.release]
debug = true
- LTO - Link-Time Optimization
Link-time optimization (LTO) is a whole-program optimization technique that can improve runtime performance by 10-20% or more, at the cost of increased build times. InCargo.toml
.
[profile.release]
lto = true
- Codegen Units
The Rust compiler splits your crate into multiple codegen units to parallelize (and thus speed up) compilation. However, this might cause it to miss some potential optimizations. This will optimize it as a all, not dividing into more than one units. You have to benchmark it, because it can run faster or in some cases slower. InCargo.toml
.
[profile.release]
codegen-units = 1
- Using CPU Specific Instructions - Compiling to native CPU features.
It identifies and optimizes for the features of your CPU used in the compilation machine.
$ RUSTFLAGS="-C target-cpu=native" cargo build --release
-
PGO - Profile-Guided Optimization Profile-guided optimization (PGO) is a compilation model where you compile your program, run it on sample data while collecting profiling data, and then use that profiling data to guide a second compilation of the program.
Exploring PGO for the Rust compiler
https://blog.rust-lang.org/inside-rust/2020/11/11/exploring-pgo-for-the-rust-compiler.html
Profile Guided Optimization
https://doc.rust-lang.org/rustc/profile-guided-optimization.html -
BOLT - Linux ELF Layout Optimization
BOLT (Facebook/Meta project) has merged into LLVM code tree.
The BOLT + LTO + PGO combination gives a impressive performance uplift (34 % to 68.5 %) to many Clang (LLVM) and GCC compiled programs, see article below. Including the Kernel, and even the Clang and GCC compilers execution.
BOLT Merged Into LLVM To Optimize Binaries For Faster Performance
https://www.phoronix.com/scan.php?page=news_item&px=LLVM-Lands-BOLT
Facebook Has Been Working On BOLT'ing The Linux Kernel For Greater Performance
https://www.phoronix.com/scan.php?page=news_item&px=Facebook-BOLTing-The-Kernel
GitHub - BOLT
https://github.com/facebookincubator/BOLT/tree/main/bolt -
Optimize for small executable binary size with no vectorization
[profile.release]
opt-level = z
Rust bounds check removal
This forum thread shows well some ways to remove bounds check without the need to do a loop for and a iterator, the case where bounds check are automatically removed, or without using the manual way get_unchecked()
.
- Is bound checking the only runtime cost of Rust?
https://users.rust-lang.org/t/is-bound-checking-the-only-runtime-cost-of-rust/66661
I have put here some examples from the previous forum thread of bounds check removal with a simple assert. Imagine that you have a loop with a index array that the compiler can’t easily know that it doesn’t need to bounds check a easy way to ensure that the bounds check will be removed is with the introduction of an assert that will assure to the compiler it is safe. In this case the assert only makes one bounds check outside a loop and all the bounds checks inside the look will disappear.
// Instead of….
for i in array1.len() {
println!("{} {}", array1[i], array2[i]);
}
// Do….
assert_eq!(array1.len(), array2.len());
for i in array1.len() {
println!("{} {}", array1[i], array2[i]);
}
// This does three bounds checks
pub fn demo1(x: &[i32]) -> i32 {
x[0] + x[1] + x[2]
}
// Whereas these two examples each only have one bounds check:
pub fn demo2(x: &[i32]) -> i32 {
assert!(x.len() >= 3);
x[0] + x[1] + x[2]
}
pub fn demo3(x: &[i32]) -> i32 {
let x = &x[..3];
x[0] + x[1] + x[2]
}
- Removal of bounds checks in extreme cases.
Rust has slice, array and Vec bounds checks for each indices.
If you use iterators there will be no bounds check.
But in the common case Rust uses LLVM, and LLVM does a very good job at removing the bounds checks that aren't needed.
But if you need the fastest code implementation and want to remove bounds check, you can useget_unchecked()
andget_unchecked_mut()
, they must be inside a unsafe block.
let x = &mut [1, 2, 4];
unsafe {
let elem = x.get_unchecked_mut(1);
*elem = 13;
}
assert_eq!(x, &[1, 13, 4]);
- For the use case of 2D Vec
get_unchecked_mut()
see the following code and benchmarks.
Performance of naive matrices in rust
https://gist.github.com/TianyiShi2001/7f83854b91a94f3eaf3145084db6d627
// Normal performance: 84,694,933 ns/iter (+/- 7,412,836)
// This optimization: 41,440,947 ns/iter (+/- 752,463) [x2 times faster]
fn bench_vec_of_vec_unsafe(b: &mut Bencher) {
let (m, n) = (10000, 10000);
let mut matrix = vec![vec![0u8; n]; m];
b.iter(|| {
for i in 0..m {
for j in 0..n {
unsafe {
*matrix.get_unchecked_mut(i).get_unchecked_mut(j) = 1u8;
}
}
}
});
}
Notes - General
- Enum Option - Option.copied()
// y_copy is a new Option of the cloned char 'a'.
// x is Option<&T> and the y_copy is Option .
let c: char = 'a';
let x: Option<&char> = Some(&c);
let y_copy: Option<char> = x.copied(); // => Option
- Trait Iterator - Iterator.copied()
Example modified from std lib docs.
// Trait Iterator - Iterator.copied()
// Creates an iterator which copies all of its elements.
// This is useful when you have an iterator over &T, but you need an iterator over T.
let a = [1, 2, 3];
{
// Vector of references &T , &i32
let v_copied_ref: Vec<&i32> = a.iter().collect();
}
// Vector of copied items T , i32
let v_copied: Vec<i32> = a.iter().copied().collect();
// You should write the Vec type like this "vec<_>".
// let v_copied: Vec<_> = a.iter().copied().collect();
// Copied is the same as .map(|&x| x)
let v_map: Vec<_> = a.iter().map(|&x| x).collect();
assert_eq!(v_copied, vec![1, 2, 3]);
assert_eq!(v_map, vec![1, 2, 3]);
// Better and faster to just transform an array into a Vec.
let v_copied_2 = a.to_vec();
assert_eq!(v_copied_2, vec![1, 2, 3]);
Notes on optimization
-
A good example of applying optimization technics to a high performance Rust program.
Writing the Fastest GBDT Library in Rust by Isabella Tromba - RustConf 2021
https://www.youtube.com/watch?v=D1NAREuicNs -
ndarray - N dimensional array
Crate ndarray
https://crates.io/crates/ndarray
Rust by example - N Dimensional arrays
https://rust-by-example-ext.com/ndarray.html
ndarray for numpy users
https://docs.rs/ndarray/0.12.1/ndarray/doc/ndarray_for_numpy_users/index.html
Rust Cookbook - Linear Algebra
https://rust-lang-nursery.github.io/rust-cookbook/science/mathematics/linear_algebra.html
Multidimensional Arrays and Operations with NDArray
https://datacrayon.com/posts/programming/rust-notebooks/multidimensional-arrays-and-operations-with-ndarray/
ndarray-examples
https://github.com/rust-ndarray/ndarray-examples
For examples of usage, see ndarray project github in the folders examples and tests
https://github.com/rust-ndarray/ndarray -
smallvec - "Small vector" optimization for Rust: store up to a small number of items on the stack.
https://crates.io/crates/smallvec -
The HashMap in Rust uses strong cryptographic hashing for security reasons, but if the developer needs the fastest HashMap performance it can use an external faster and less secure hash function.
HashMap.with_hasher() info
https://doc.rust-lang.org/beta/std/collections/struct.HashMap.html#method.with_hasher
Insert crate fasthash into.toml
file
use std::collections::HashMap;
use fasthash::murmur2::Murmur2_x86_64;
let s = Murmur2_x86_64::new();
let mut map = HashMap::with_hasher(s);
map.insert(1, 2);
- But for a even faster HashMap or HashSet use,
hashbrown - Faster drop in replacement for STD HashMap and HashSet, a Rust port of Google's high-performance SwissTable hash map.
https://github.com/Amanieu/hashbrown
Insert crate hashbrown into.toml
file
// The fastest HashMap for Rust. HashBrown a drop in replacement for std HashMap.
use hashbrown::HashMap;
-
bstr - A fast string type that is not required to be valid UTF-8. No heavy UTF-8 validations.
https://crates.io/crates/bstr -
SmartString with LTO (global Link-Time Optimization)
It’s a general faster (2.5x faster) string replace for small strings <= 23 bytes (23 ASCII characters ex: “Mary had a little lamb!”) that are only stack allocated, but with the same performance as String for longer strings that are heap allocated.
Rust benchmark String vs SmartString and LTO
https://github.com/joaocarvalhoopen/Rust_benchmark_String_vs_SmartString_and_LTO
Crate SmartString
https://crates.io/crates/smartstring
// In main do.
smartstring::validate();
{
// In the scope, add the alias to replace normal Strings with SmartString.
use smartstring::alias::String;
// When creating SmartString's from &str instead of doing:
"blabla".to_string()
// Do:
String::from("blabla")
}
-
bumpalo - A fast bump heap allocation arena for Rust.
https://crates.io/crates/bumpalo -
How to use multiple variables in Rust's for loop?
https://stackoverflow.com/questions/43302808/how-to-use-multiple-variables-in-rusts-for-loop -
The ASM! macro to insert inline Assembly
New inline assembly syntax
https://blog.rust-lang.org/inside-rust/2020/06/08/new-inline-asm.html
ASM! at the Unstable Book
https://doc.rust-lang.org/beta/unstable-book/library-features/asm.html
Rust substring processing
-
Rust string processing is kind of hard, because text in a UTF-8 world has many complex details, and Rust exposes all that power and all that complexity to you, the programmer. Sometimes it can be over whelming. Sometimes you only want to have a simple substring or a slice and you don’t mind to pay it’s cost, because you really need this feature and the Standard Library doesn’t help you a lot there.
-
Fortunately carlomilanesi made this code available to all
https://users.rust-lang.org/t/how-to-get-a-substring-of-a-string/1351/11 -
But if you have to do many text operations based on the positions of chars inside a strings this isn’t a really good option, because you have to scan all the strings to the correct position, from the start, to have the string divided it into the correct boundaries of the chars. In this context, you would happily pay a up front cost of transforming the string into a Vec, Vec of chars with individual chars separated, and process it as positional chars with access cost of 1 and then, slice them, range them, append to them at the end (or if you need to append in the start or the middle paying the cost of copy to a new buffer, but you can do it if you need to). The following code is my expansion to the code of carlomilanesi. It will allow you to do it.
You can find it also in my GitHub repository in… -
SubStrings, Slices and Random String Access in Rust
https://github.com/joaocarvalhoopen/SubStrings_Slices_and_Random_String_Access_in_Rust
use std::ops::{Bound, RangeBounds}; trait StringUtils { fn substring(&self, start: usize, len: usize) -> &str; fn slice(&self, range: impl RangeBounds<usize>) -> &str; fn get_vec_chars(&self) -> Vec<char>; } impl StringUtils for str { fn substring(&self, start: usize, len: usize) -> &str { let mut char_pos = 0; let mut byte_start = 0; let mut it = self.chars(); loop { if char_pos == start { break; } if let Some(c) = it.next() { char_pos += 1; byte_start += c.len_utf8(); } else { break; } } char_pos = 0; let mut byte_end = byte_start; loop { if char_pos == len { break; } if let Some(c) = it.next() { char_pos += 1; byte_end += c.len_utf8(); } else { break; } } &self[byte_start..byte_end] } fn slice(&self, range: impl RangeBounds<usize>) -> &str { let start = match range.start_bound() { Bound::Included(bound) | Bound::Excluded(bound) => *bound, Bound::Unbounded => 0, }; let len = match range.end_bound() { Bound::Included(bound) => *bound + 1, Bound::Excluded(bound) => *bound, Bound::Unbounded => self.len(), } - start; self.substring(start, len) } fn get_vec_chars(&self) -> Vec<char> { self.chars().collect() } } trait StringUtilsVecChars { fn to_string(&self) -> String; fn to_string_buf<'a>(&self, buf: & 'a mut String) -> & 'a String; } impl StringUtilsVecChars for Vec<char> { fn to_string(&self) -> String { self.iter().collect() } fn to_string_buf<'a>(&self, buf: & 'a mut String) -> & 'a String { buf.clear(); for c in self.iter() { buf.push(*c); } buf } } trait StringUtilsSlices { fn to_string(&self) -> String; fn to_string_buf<'a>(&self, buf: & 'a mut String) -> & 'a String; } impl StringUtilsSlices for [char] { fn to_string(&self) -> String { self.iter().collect() } fn to_string_buf<'a>(&self, buf: & 'a mut String) -> & 'a String { buf.clear(); for c in self.iter() { buf.push(*c); } buf } } fn main() { let s = "abcdèfghij"; // All three statements should print: // "abcdè, abcdèfghij, dèfgh, dèfghij." println!("{}, {}, {}, {}.", s.substring(0, 5), s.substring(0, 50), s.substring(3, 5), s.substring(3, 50)); println!("{}, {}, {}, {}.", s.slice(..5), s.slice(..50), s.slice(3..8), s.slice(3..)); println!("{}, {}, {}, {}.", s.slice(..=4), s.slice(..=49), s.slice(3..=7), s.slice(3..)); // Allocating a string from Vec. let mut vc = s.get_vec_chars(); println!("{}, {}, {}, {}.", vc[..5].to_string(), vc.to_string(), vc[3..8].to_string(), vc[3..].to_string()); // Reusing a String buffer from a Vec. let mut buf = String::new(); print!("{}, ", vc[..5].to_string_buf(& mut buf)); print!("{}, ", vc[..].to_string_buf(& mut buf)); print!("{}, ", vc[3..8].to_string_buf(& mut buf)); print!("{}.\n", vc[3..].to_string_buf(& mut buf)); // Random access to the Vec. for i in 0..(vc.len() - 2) { print!("{} ", vc[i..i+3].to_string_buf(& mut buf)); } println!(""); // Random modifications to the Vec. for i in (0..(vc.len() / 3) + 1).rev() { vc.insert(i*3, '#'); } println!("{} ", vc.to_string()); println!("{} ", vc.to_string_buf(& mut buf)); } // Output: // abcdè, abcdèfghij, dèfgh, dèfghij. // abcdè, abcdèfghij, dèfgh, dèfghij. // abcdè, abcdèfghij, dèfgh, dèfghij. // // abcdè, abcdèfghij, dèfgh, dèfghij. // abcdè, abcdèfghij, dèfgh, dèfghij. // abc bcd cdè dèf èfg fgh ghi hij // #abc#dèf#ghi#j // #abc#dèf#ghi#j
Macros in Rust
-
Macro file visibility rules
https://users.rust-lang.org/t/3-things-that-the-rust-standard-library-should-have/68825/11 -
Macros for hashMap, hashset, btreeMap, btreeSet to look similar to Python
Crate maplit
https://crates.io/crates/maplit
#[macro_use] extern crate maplit; let map = hashmap!{ "a" => 1, "b" => 2, }; let map1: HashMap<String, String> = convert_args!(hashmap!( "a" => "b", "c" => "d", )); let map2 = convert_args!(keys=String::from, hashmap!( "a" => 1, "c" => 2, ));
- Macro for graph's
See the following post from kaj, on the Rust user foruns.
https://users.rust-lang.org/t/3-things-that-the-rust-standard-library-should-have/68825/9
# When you have the following dictionary Python code...
# Adjacency list of graph
data = {
0: [1, 2],
1: [0, 2],
2: [0, 1, 3, 5],
}
// And you implement it in Rust like this...
let data = HashMap::from([
(0, vec![1, 2]),
(1, vec![0, 2]),
(2, vec![0, 1, 3, 5]),
]);
// ...but you can instead implement it like this...
let data2 = graph![
0 => 1, 2;
1 => 0, 2;
2 => 0, 1, 3, 5
];
// ...using the following simple Macro...
use std::collections::HashMap;
macro_rules! graph {
[$($k:expr => $($v:expr),*);*] => {
HashMap::from([
$(($k, vec![ $($v),* ])),*
])
}
}
Good way to learn about the topic of computers and programming
- Video - Computer Science - Crash Course
https://www.youtube.com/playlist?list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo
For a good challenge do the NAND To Tetris in Rust
-
From Nand to Tetris
Building a Modern Computer From First Principles
https://www.nand2tetris.org/ -
Video - Shimon Schocken: The self-organizing computer course
https://www.youtube.com/watch?v=iE7YRHxwoDs -
Video - From Nand to Tetris Part I Course Promo
https://www.youtube.com/watch?v=wTl5wRDT0CU -
Free Course - Build a Modern Computer from First Principles
From Nand to Tetris (Project-Centered Course)
https://www.coursera.org/learn/build-a-computer -
Free Course - Build a Modern Computer from First Principles
Nand to Tetris Part II (project-centered course)
https://www.coursera.org/learn/nand2tetris2
All my other guides
- The links to all my guides are in:
Guides on Linux - Programming - Embedded - Electronics - Aeronautics
https://github.com/joaocarvalhoopen/Guides_Linux-Programming-Electronics-Aeronautics
Have fun
Best regards,
Joao Nuno Carvalho