Видео доклада: https://www.youtube.com/watch?v=slnQBoxsHPU
Rust - системный язык программирования, который быстро исполняется, предотвращает почти все падения, и устраняет гонки по данным.
Как он этого достигает? Про это доклад.
1 of 45
More Related Content
Почему Rust стоит вашего внимания
1. Почему Rust стоит вашего внимания
Панков Михаил
14 мая 2015 г.
Панков Михаил Почему Rust стоит вашего внимания
2. Что такое Rust
Безопасность работы с памятью
Безопасные: Java, C#, Python, Ruby
Опасные: C, C++
Среда исполнения и эффективность
Байт-код, большая среда и сборщик мусора: Java, C#, ...
Машинный код, маленькая среда, ручное управление
памятью: C, C++
Rust
Безопасный, при этом компилируется в машинный код
Проще встраивать
Проще профилировать
Статически гарантирует безопасность работы с памятью
Панков Михаил Почему Rust стоит вашего внимания
3. Что такое Rust (продолжение)
Rust — системный язык программирования, который быстро
работает, предотвращает почти все падения, и устраняет гонки
по данным.
Панков Михаил Почему Rust стоит вашего внимания
4. Hello World
1 fn main() {
2 println!("Привет, мир!");
3 }
Панков Михаил Почему Rust стоит вашего внимания
5. Детсадовский калькулятор
1 fn main() {
2 let program = "+ + * - /";
3 let mut accumulator = 0;
4 for token in program.chars() {
5 match token {
6 ’+’ => accumulator += 1,
7 ’-’ => accumulator -= 1,
8 ’*’ => accumulator *= 2,
9 ’/’ => accumulator /= 2,
10 _ => { /* игнорируем всё остальное */ }
11 }
12 }
13 println!("Программа "{}" вычислила значение {}",
14 program, accumulator);
15 }
Панков Михаил Почему Rust стоит вашего внимания
6. Перемещение по умолчанию
1 let v = vec![1, 2, 3];
2
3 let v2 = v;
4
5 println!("v[0] is: {}", v[0]);
error: use of moved value: ‘v‘
println!("v[0] is: {}", v[0]);
^
Панков Михаил Почему Rust стоит вашего внимания
7. Перемещение по умолчанию (продолжение)
1 fn take(v: Vec<i32>) {
2 // что здесь происходит - неважно
3 }
4
5 let v = vec![1, 2, 3];
6
7 take(v);
8
9 println!("v[0] is: {}", v[0]);
error: use of moved value: ‘v‘
println!("v[0] is: {}", v[0]);
^
Панков Михаил Почему Rust стоит вашего внимания
8. Как использовать освобождённую память
1 void * allocate_new_buffer(size_t number)
2 {
3 return malloc(number * sizeof (int));
4 }
5 int main(int argc, char *argv[])
6 {
7 int *numbers = allocate_new_buffer(10);
8 for (int i = 0; i < 10; ++ i) {
9 numbers[i] = i;
10 }
11 // ...
12 free(numbers);
13 // ...
14 }
Панков Михаил Почему Rust стоит вашего внимания
9. Как использовать освобождённую память (продолжение)
1 void * allocate_new_buffer(size_t number); //...
2 int main(int argc, char *argv[])
3 {
4 int *numbers = allocate_new_buffer(10);
5 for (int i = 0; i < 10; ++ i) {
6 numbers[i] = i;
7 }
8 // ...
9 free(numbers);
10 // ...
11 for (int i = 0; i < 10; ++ i) {
12 printf("%d ", numbers[i]);
13 }
14 }
Панков Михаил Почему Rust стоит вашего внимания
10. Как обратиться к освобождённой памяти в Rust
1 fn allocate_new_buffer(number: usize) -> Vec<isize> {
2 return Vec::with_capacity(number);
3 }
4 fn main() {
5 let mut numbers = allocate_new_buffer(10);
6 numbers.extend(0..10);
7 // ...
8 drop(numbers);
9 // ...
10 println!("{:?}", numbers);
11 // ^^^^^^^
12 // error: use of moved value
13 }
Панков Михаил Почему Rust стоит вашего внимания
11. Идиоматичный код на Rust
1 fn main() {
2 let numbers: Vec<_> = (0..10).collect();
3 // ...
4 println!("{:?}", numbers);
5 // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6 // неявный вызов drop(numbers)
7 }
Панков Михаил Почему Rust стоит вашего внимания
12. Заимствование
1 fn main() {
2 let mut x = 42;
3 let y = &mut x;
4 *y = 43;
5 x = 44;
6 }
5:11 error: cannot assign to ‘x‘ because it is borrowed
x = 44;
^~~~~~
3:19 note: borrow of ‘x‘ occurs here
let y = &mut x;
^
error: aborting due to previous error
Панков Михаил Почему Rust стоит вашего внимания
13. Изменяемость
1 void process(std::string input)
2 {
3 for (auto i = input.begin(); i != input.end(); ++ i) {
4 if (*i == ’o’) {
5 input.push_back(’z’);
6 }
7 }
8 std::cout << input;
9 }
10 int main(int argc, char *argv[])
11 {
12 auto string = "Hello world";
13 process(string);
14 return 0;
15 }
Панков Михаил Почему Rust стоит вашего внимания
14. Изменяемость в Rust
1 fn process(input: String) {
2 for c in input.chars() {
3 if c == ’o’ {
4 input.push(’z’);
5 // ^^
6 // Cannot borrow immutable local variable
7 // as mutable
8 }
9 }
10 }
11
12 fn main() {
13 let string = "Hello world".to_string();
14 process(string);
15 }
Панков Михаил Почему Rust стоит вашего внимания
15. Изменяемость в Rust (продолжение)
1 fn process(mut input: String) {
2 for c in input.chars() {
3 // ^^^^^
4 // previous borrow occurs here
5 if c == ’o’ {
6 input.push(’z’);
7 // ^^
8 // Cannot borrow ‘input‘ as mutable
9 // because it’s also borrowed as immutable
10 }
11 }
12 }
13 fn main() {
14 let string = "Hello world".to_string();
15 process(string);
16 }
Панков Михаил Почему Rust стоит вашего внимания
16. Время жизни
1 struct Foo<’a> {
2 x: &’a i32,
3 }
4 fn main() {
5 let x; // -+ x оживает
6 // |
7 { // |
8 let y = &5; // ---+ y оживает
9 let f = Foo { x: y }; // ---+ f оживает
10 x = &f.x; // | | здесь ошибка
11 } // ---+ f и y умирают
12 // |
13 println!("{}", x); // |
14 } // -+ x умирает
Панков Михаил Почему Rust стоит вашего внимания
17. Обобщённое программирование. Типажи
1 struct Circle {
2 x: f64,
3 y: f64,
4 radius: f64,
5 }
6 trait HasArea {
7 fn area(&self) -> f64;
8 }
9 impl HasArea for Circle {
10 fn area(&self) -> f64 {
11 std::f64::consts::PI * (self.radius * self.radius)
12 }
13 }
Панков Михаил Почему Rust стоит вашего внимания
18. Обобщённое программирование. Ограничения
1 fn print_area<T>(shape: T) {
2 println!("Площадь фигуры: {}", shape.area());
3 }
4 // error: type ‘T‘ does not implement any method in scope
5 // named ‘area‘
6
7 fn print_area<T: HasArea>(shape: T) {
8 println!("Площадь фигуры: {}", shape.area());
9 }
10 // ok
Панков Михаил Почему Rust стоит вашего внимания
19. RAII в Rust
1 pub struct Fd {
2 raw_fd: c95_t::c_int,
3 }
4 impl Fd {
5 pub fn open(path: &str) -> Result<Fd, i32> {
6 let c_path = CString::new(path).unwrap();
7 let fd = unsafe {
8 posix88_f::fcntl::open(c_path.as_ptr(),
9 posix88_c::O_RDONLY, 0)
10 } as i32;
11 if fd > -1000 && fd < 0 {
12 return Err(-fd);
13 }
14 Ok(Fd { raw_fd: fd })
15 }
Панков Михаил Почему Rust стоит вашего внимания
20. RAII в Rust (продолжение)
1 pub fn raw(&self) -> c95_t::c_int {
2 self.raw_fd
3 }
4 pub fn get_size(&self) -> Result<i64, i32> {
5 // ...
6 Ok(file_info.st_size)
7 }
8 }
9 impl Drop for Fd {
10 fn drop(&mut self) {
11 unsafe {
12 posix88_f::unistd::close(self.raw_fd);
13 }
14 }
15 }
Панков Михаил Почему Rust стоит вашего внимания
21. RAII в Rust (использование)
1 fn read_print_file(path: &str) -> Result<(), ()> {
2 let maybe_fd = fd::Fd::open(path);
3 let fd: fd::Fd;
4 match maybe_fd {
5 Ok(f) => fd = f,
6 Err(errno) => {
7 print_error(
8 &format!("Couldn’t open file: {}", c_helpers
9 return Err(());
10 }
11 }
12 let mut remaining_file_size = fd.get_size().unwrap();
Панков Михаил Почему Rust стоит вашего внимания
22. Обрабатываем ошибки идиоматично
1 fn read_print_file(path: &str) -> Result<(), ()> {
2 let maybe_fd = fd::Fd::open(path);
3 let fd = match maybe_fd {
4 Ok(f) => f,
5 Err(errno) => {
6 print_error(
7 &format!("Couldn’t open file: {}", c_helpers
8 return Err(());
9 }
10 }
11 let mut remaining_file_size = fd.get_size().unwrap();
Панков Михаил Почему Rust стоит вашего внимания
23. Ложь и бенчмарки
$ ls -l /boot/memtest86+.elf
-rw-r--r-- 1 root root 178176 марта 12 2014 /boot/memtest86
$ time hd /boot/memtest86+.elf
...
hd /boot/memtest86+.elf 0,11s user 0,06s system
8% cpu 1,929 total
$ time hexdump/hexdump /boot/memtest86+.elf
...
hexdump/hexdump /boot/memtest86+.elf 0,06s user 0,07s syste
6% cpu 2,031 total
$ time rexdump/rexdump /boot/memtest86+.elf
...
./rexdump /boot/memtest86+.elf 0,14s user 0,07s system
10% cpu 2,056 total
$
Панков Михаил Почему Rust стоит вашего внимания
24. Ложь и бенчмарки (продолжение)
C — BSD C — моя Rust — моя
0
0.2
0.4
0.6
0.8
1
0.9
относительноебыстродействие
Панков Михаил Почему Rust стоит вашего внимания
25. Как устроить гонку по данным
1 THREADS = 10
2 COUNT = 50
3 $x = 1
4 THREADS.times.map { |t|
5 Thread.new {
6 COUNT.times { |c|
7 a = $x + 1
8 sleep 0.001
9 puts "Thread #{t} wrote #{a}"
10 $x = a
11 }
12 }
13 }.each(&:join)
14 puts "Got $x = #{$x}."
Панков Михаил Почему Rust стоит вашего внимания
26. Потокобезопасный код на Rust: попытка 0
1 fn main() {
2 let threads = 10;
3 let count = 50;
4 let mut x = 1;
5 for _ in 0..threads {
6 std::thread::spawn(|| {
7 for _ in 0..count {
8 let a = x + 1; // error: closure borrows x
9 std::thread::sleep_ms(1);
10 x = a;
11 }
12 });
13 }
14 println!("The result is {}", x);
15 }
Панков Михаил Почему Rust стоит вашего внимания
27. Что говорит компилятор
data-race.rs:6:28: 12:10 error: closure may outlive the
current function, but it borrows ‘x‘,
which is owned by the current function [E0373]
data-race.rs:6 std::thread::spawn(|| {
data-race.rs:7 for _ in 0..count {
data-race.rs:8 let a = x + 1;
data-race.rs:9 std::thread::sleep_ms(1);
data-race.rs:10 x = a;
data-race.rs:11 }
...
data-race.rs:8:25: 8:26 note: ‘x‘ is borrowed here
data-race.rs:8 let a = x + 1;
^
Панков Михаил Почему Rust стоит вашего внимания
28. Потокобезопасный код на Rust: попытка 1
1 fn main() {
2 let threads = 10;
3 let count = 50;
4 let mut x = 1;
5 for _ in 0..threads {
6 thread::scoped(|| { // warning: thread will be
7 for _ in 0..count { // immideately joined
8 let a = x + 1;
9 thread::sleep_ms(1);
10 x = a;
11 }
12 });
13 }
14 println!("The result is {}", x);
15 }
Панков Михаил Почему Rust стоит вашего внимания
29. Потокобезопасный код на Rust: попытка 2
1 // ...
2 let mut guards: Vec<JoinGuard<()>> = Vec::new();
3 for _ in 0..threads {
4 let g: JoinGuard<()> =
5 thread::scoped(|| {
6 for _ in 0..count {
7 let a = x + 1; // error: cannot borrow ‘x‘
8 thread::sleep_ms(1); // mutably borrowed
9 x = a;
10 }
11 });
12 guards.push(g);
13 }
14 drop(guards);
15 println!("The result is {}", x);
Панков Михаил Почему Rust стоит вашего внимания
30. Рабочий потокобезопасный код на Rust
1 fn main() {
2 let threads = 10;
3 let count = 50;
4 let x = &AtomicUsize::new(1);
5 let _: Vec<_> = (0..threads).map(|_| {
6 thread::scoped(move || {
7 for _ in 0..count {
8 thread::sleep_ms(1);
9 x.fetch_add(1, Ordering::SeqCst);
10 }
11 })
12 }).collect();
13 println!("The result is {}", x.load(Ordering::SeqCst));
14 }
Панков Михаил Почему Rust стоит вашего внимания
31. Тестирование
1 #[test]
2 fn it_works() {
3 assert_eq!(4, add_two(2));
4 }
$ cargo test
Compiling adder v0.0.1 (file:///home/you/projects/adder)
Running target/adder-91b3e234d4ed382a
running 1 test
test it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Doc-tests adder
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
Панков Михаил Почему Rust стоит вашего внимания
32. Бенчмарки
1 #[bench]
2 fn bench_add_two(b: &mut Bencher) {
3 b.iter(|| add_two(2));
4 }
$ cargo bench
Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
Running target/release/adder-91b3e234d4ed382a
running 2 tests
test tests::it_works ... ignored
test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)
test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
Панков Михаил Почему Rust стоит вашего внимания
33. Стабильность
master: A - B - C - .... - G - H - I - J - K
beta: . - K’
stable: . - I’ - J’ - K’
| |
1.0.0: . - E’ - G’ | |
| | |
1.0.1: . - I’ | |
| |
1.1.0: . |
|
1.1.1: .
Панков Михаил Почему Rust стоит вашего внимания
35. Инфраструктура
Crates.io — 2000 контейнеров
Разработка языка на GitHub
Изменения через RFC из основной команды или
сообщества
Панков Михаил Почему Rust стоит вашего внимания
41. Кто уже использует Rust
Servo
400 тысяч строк кода
4-х поточная версия отрисовывает Reddit в 5 раз быстрее
Gecko (55 против 250 миллисекунд)
Piston
hematite — клон Minecraft
Iron
84 тысячи запросов в секунду для простейшего сервера
Панков Михаил Почему Rust стоит вашего внимания
42. 84 тысячи запросов в секунду
http://www.yesodweb.com/blog/2011/03/
preliminary-warp-cross-language-benchmarks
Панков Михаил Почему Rust стоит вашего внимания
43. Кто уже использует Rust (продолжение)
OpenDNS
Skylight
MaidSafe
Панков Михаил Почему Rust стоит вашего внимания
44. Ресурсы
Книга «Язык программирования Rust»
https://github.com/kgv/rust_book_ru
IRC канал на русском
http://client00.chat.mibbit.com/?server=irc.
mozilla.org&channel=%23rust-ru
Русский StackOverflow — тег Rust
http://ru.stackoverflow.com/questions/tagged/rust
Лента событий на Timepad
https://rust-v-moskve.timepad.ru/
Веб-интерфейс к компилятору
http://play.rust-lang.org/
Домашняя страница со ссылками на англоязычные
ресурсы
http://www.rust-lang.org
Панков Михаил Почему Rust стоит вашего внимания
45. Где найти этот доклад
http://michaelpankov.com/why-rust-matters.pdf
Панков Михаил Почему Rust стоит вашего внимания