Rust + Node = Neon

2e36436c692b2e5fbc172e9fb7563171?s=47 dherman
November 17, 2016

Rust + Node = Neon

I presented Neon, a system for writing native Node.js modules using Rust, at the Bay Area Rust Meetup.

Video at: https://youtu.be/jINMIAicaS0

2e36436c692b2e5fbc172e9fb7563171?s=128

dherman

November 17, 2016
Tweet

Transcript

  1. N E O N R U S T + N

    O D E =
  2. A whole new generation of systems programmers…

  3. None
  4. None
  5. None
  6. • Dip your toe in • Performance • Easy integration

    of native libraries • Hack without fear: safety first!
  7. None
  8. None
  9. #[macro_use] extern crate neon; use /* ... */; fn hello(call:

    Call) -> JsResult<JsString> { Ok(JsString::new(call.scope, "hello node").unwrap()) } register_module!(m, { m.export("hello", hello) });
  10. #[macro_use] extern crate neon; use /* ... */; fn hello(call:

    Call) -> JsResult<JsString> { Ok(JsString::new(call.scope, "hello node").unwrap()) } register_module!(m, { m.export("hello", hello) }); ?
  11. init_obj init_prop set_prop initObject eventHandler JavaScript Rust Object::set setter V8

    GC'ed Heap JavaScript
  12. init_obj init_prop set_prop initObject eventHandler JavaScript Rust Object::set setter V8

    GC'ed Heap JavaScript
  13. init_obj init_prop set_prop initObject eventHandler JavaScript Rust Object::set setter V8

    GC'ed Heap JavaScript
  14. None
  15. var total = 0; for (var i = 0, n

    = lines.length; i < n; i++) { total += wcLine(lines[i], "thee"); }
  16. function wcLine(line, search) { var words = line.split(' '); var

    total = 0; for (var i = 0, n = words.length; i < n; i++) { if (matches(words[i], search)) { total++; } } return total; } 280ms
  17. fn wc_line(line: &str, search: &str) -> i32 { let mut

    total = 0; for word in line.split(' ') { if matches(word, search) { total += 1; } } total } 85ms
  18. fn wc_line(line: &str, search: &str) -> i32 { line.split(' ')

    .filter(|word| matches(word, search)) .fold(0, |sum, _| sum + 1) }
  19. fn wc_line(line: &str, search: &str) -> i32 { line.split(' ')

    .filter(|word| matches(word, search)) .fold(0, |sum, _| sum + 1) } lines.into_iter() .map(|line| wc_line(line, search)) .sum()
  20. fn wc_line(line: &str, search: &str) -> i32 { line.split(' ')

    .filter(|word| matches(word, search)) .fold(0, |sum, _| sum + 1) } lines.into_par_iter() .map(|line| wc_line(line, search)) .sum() 50ms
  21. fn wc_line(line: &str, search: &str) -> i32 { line.split(' ')

    .filter(|word| matches(word, search)) .fold(0, |sum, _| sum + 1) } lines.into_par_iter() .map(|line| wc_line(line, search)) .sum() 50ms
  22. let mut buffer = call.arguments.require(scope, 0)? .check::<JsBuffer>()?; let total =

    buffer.grab(|data| { let corpus = str::from_utf8(data.as_slice()).unwrap(); wc(&lines(corpus), "thee") }); Ok(JsInteger::new(scope, total))
  23. None
  24. struct Greeter { greeting: String } declare_types! { pub class

    JsGreeter for Greeter { init(greeting: String) { Ok(Greeter { greeting: greeting }) } method hello(call: Call) { let scope = call.scope; let name = call.arguments.require(scope, 0)?.check::<JsString>()?; let message = call.arguments.this(scope).grab(|greeter| { format!("{}, {}!", greeter.greeting, name) }); Ok(JsString::new(scope, message).unwrap()) } } }
  25. module! { export class JsGreeter for Greeter { init(greeting: String)

    { Ok(Greeter { greeting: greeting }) } method hello(name: String) -> String { Ok(self.arguments.this(self.scope).grab(|g| { format!("{}, {}!", g.greeting, name) })) } } }
  26. module! { export function add1(x: i32) -> i32 { Ok(x

    + 1) } }
  27. A few caveats: • Currently better for apps than libs.

    • Calling from JS to Rust costs, so make it worth it. • I keep falling asleep in my comfy hacking chair!
  28. https://github.com/rustbridge/neon Thank you!

  29. I M A G E C R E D I

    T S • https://unsplash.com/photos/Niy6KKRAu1Y • https://www.youtube.com/watch?v=N1icEHtgb3g • http://www.sideshowtoy.com/collectibles/the-hobbit-gandalf-the-grey-asmus-collectible-toys-902681/ • https://www.rust-lang.org/logos/rust-logo-512x512-blk.png • https://nodejs.org/static/images/logos/nodejs-new-white-pantone.png • https://www.flickr.com/photos/morgennebel/11854357125/in/photolist-j4wFnF-poSvWa-9F81pt-poCWZL-pwJLS8- o1WiLo-87zwv6-rEfLQD-9adjGY-g5WKTT-g5W4UA-psQtns-fddieS-rn4gXZ-pnjo8R-e9Ck2i-kD5gZX-CCXFqE-eb6pxd- g5WniL-ey9Qs1-cJofsb-6vvL1M-nRgkhR-6edC3p-kHEzPp-4zYFsi-U7wt9-fJU62F-ssgkaY-qJehyN-kUfLJx-qLndLK- fiHPW7-ffAfAq-ieJcgA-ieJiDo-rcvDPd-e9CptH-pwJEX2-ieJgyo-cxR34J-cgc7pj-3dBYvj-eFBMJJ-9hEsh5-avugjT- cgc6Wm-ieHQLr-fHDYpN • http://www.anonymousproductionassistant.com/wp-content/uploads/2016/10/main_freereports.jpg • https://www.youtube.com/watch?v=jDQaIl_1Nfk • https://www.youtube.com/watch?v=8ud6haTTfFY • https://www.disneyclips.com/imagesnewb3/images/clipcindydream.gif