Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rust at Mozilla (part of Mozilla Onboarding)

Rust at Mozilla (part of Mozilla Onboarding)

Some slides that give a brief overview of Rust and how it is coming into use at Mozilla (part of Mozilla Onboarding)

8f9e4181f2951ca8f21ed5c541686367?s=128

nikomatsakis

March 08, 2017
Tweet

Transcript

  1. 1 Nicholas Matsakis / nmatsakis@mozilla.com / nmatsakis (IRC)

  2. 2 Photo credit: Giorgio Monteforti Systems Programming Before Rust…

  3. Hack without fear!

  4. 4 Performance class ::String def blank? /\A[[:space:]]*\z/ == self end

    end Ruby: 964K iter/sec
  5. static VALUE rb_str_blank_as(VALUE str) { rb_encoding *enc; char *s, *e;

    enc = STR_ENC_GET(str); s = RSTRING_PTR(str); if (!s || RSTRING_LEN(str) == 0) return Qtrue; e = RSTRING_END(str); while (s < e) { int n; unsigned int cc = rb_enc_codepoint_len(s, e, &n, enc); switch (cc) { case 9: case 0xa: case 0xb: case 0xc: case 0xd: case 0x20: case 0x85: case 0xa0: case 0x1680: case 0x2000: case 0x2001: case 0x2002: case 0x2003: case 0x2004: case 0x2005: case 0x2006: case 0x2007: case 0x2008: case 0x2009: case 0x200a: case 0x2028: case 0x2029: case 0x202f: case 0x205f: case 0x3000: #if ruby_version_before_2_2() case 0x180e: #endif /* found */ break; default: return Qfalse; } s += n; } return Qtrue; } Performance Ruby: 964K iter/sec C: 10.5M iter/sec 10x! https://github.com/SamSaffron/fast_blank
  6. Performance 6 class ::String def blank? /\A[[:space:]]*\z/ == self end

    end extern “C” fn fast_blank(buf: Buf) -> bool { buf.as_slice().chars().all(|c| c.is_whitespace()) } Get Rust string slice Get iterator over each character Are all characters whitespace? Rust: 11M iter/sec Ruby: 964K iter/sec C: 10.5M iter/sec
  7. 7 “Must be this tall to write multi-threaded code”

  8. Parallel Programming 8 fn load_images(paths: &[PathBuf]) -> Vec<Image> { paths.iter()

    .map(|path| { Image::load(path) }) .collect() } For each path… …load an image… …create and return a vector.
  9. Parallel Programming 9 fn load_images(paths: &[PathBuf]) -> Vec<Image> { paths.par_iter()

    .map(|path| { Image::load(path) }) .collect() } …make it parallel. extern crate rayon; Third-party library Can also do: processes with channels, mutexes, non-blocking data structures…
  10. Safer Parallel Programming 10 fn load_images(paths: &[PathBuf]) -> Vec<Image> {

    let mut jpegs = 0; paths.par_iter() .map(|path| { if path.ends_with(“jpeg”) { jpegs += 1; } Image::load(path) }) .collect(); } Data-race Will not compile
  11. Cargo and crates.io 11

  12. 12 (just a sampling)

  13. 13 From http://jvns.ca/blog/2016/09/11/rustconf-keynote/ Open and welcoming

  14. Ownership 14

  15. fn main() { let name = format!(“…”); helper(name); helper(name); }

    fn helper(name: String) { println!(..); } Ownership Take ownership of a String 15 Error: use of moved value: `name`
  16. void main() { Vector name = …; helper(name); helper(name); }

    void helper(Vector name) { … } “Ownership” in Java Take reference to Vector 16 new Thread(…);
  17. Borrowing: Shared Borrows 17

  18. Borrow the string, creating a reference fn helper(name: &String) {

    println!(..); } Shared borrow Change type to a reference to a String 18 fn main() { let name = format!(“…”); let r = &name; helper(r); helper(r); }
  19. Shared == Immutable 19 fn helper(name: &String) { println!(“{}”, name);

    } fn helper(name: &String) { name.push(‘x’); } OK. Just reads. Error. Writes. * Actually: mutation only in controlled circumstances. * error: cannot borrow immutable borrowed content `*name` as mutable name.push_str(“s”); ^^^^
  20. Borrowing: Mutable Borrows 20

  21. fn update(name: &mut String) { name.push_str(“…”); } fn main() {

    let mut name = …; update(&mut name); println!(“{}”, name); } Mutable borrow Take a mutable reference to a String 21 Lend the string mutably Mutate string in place Prints the updated string. mut
  22. 22 name: String name: &String name: &mut String Ownership: control

    all access, will free when done Shared reference: many readers, no writers Mutable reference: no other readers, one writer
  23. Play time 23 http://is.gd/no0tTH Waterloo, Cassius Coolidge, c. 1906

  24. How do we get safety? 24 https://www.flickr.com/photos/langtind/2217639550/in/photostream/

  25. Dangers of mutation 25 let mut buffer: String = format!(“Rustacean”);

    let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ … ‘n’ String data len capacity ‘R’ ‘u’ … ‘n’ data len ‘R’ ‘u’ … ‘n’ ‘s’ Dangling reference!
  26. Rust solution 26 Compile-time read-write-lock: Creating a shared reference to

    X “read locks” X. - Other readers OK. - No writers. - Lock lasts until reference goes out of scope. Creating a mutable reference to X “writes locks” X. - No other readers or writers. - Lock lasts until reference goes out of scope. Never have a reader/writer at same time.
  27. 27 fn main() { let mut buffer: String = format!(“Rustacean”);

    let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } Borrow “locks” `buffer` for lifetime `’l` of resulting reference http://is.gd/MCPVWg ‘l Rule: No mutation during lifetime of borrow. Lifetime: span of code where reference is used.
  28. ‘l fn main() { let mut buffer: String = format!(“Rustacean”);

    for i in 0 .. buffer.len() { let slice = &buffer[i..]; buffer.push_str(“s”); println!(“{:?}”, slice); } buffer.push_str(“s”); } 28 Borrow “locks” `buffer` until `slice` goes out of scope OK: `buffer` is not borrowed here
  29. 29 Play time http://is.gd/no0tTH Waterloo, Cassius Coolidge, c. 1906

  30. 30

  31. Rust in use within Gecko 31 Media stack (MP4 parser)

    • mp4 video parser written in Rust • will become default soon Style system (“stylo”) • CSS styling, in parallel • goal is to land around June Paint system (“WebRender”) • written in Rust, uses GPU • goal is end-of-year URL parser • been an exploit vector in the past • unknown date to ship …and beyond?
  32. Resources 32 intorust.com users.rust-lang.org rust-lang.github.io/book/ ❤