LINUX.ORG.RU

Презентация «Rust - лучше, чем C++» на русском языке от разработчика из Яндекса

 


7

3

http://tech.yandex.ru/events/cpp-party/june-minsk/talks/1978

Степан Кольцов

Яндекс

Rust — это современный, практический, быстрый и безопасный язык программирования. Некоторые говорят, что Rust — это как C++, если бы его писал человек, знающий Haskell.

Система типов Rust решает главную проблему C++ — небезопасность. C++ очень легко сделать ошибки, которые приведут к поломкам (например, use after free). Rust позволяет писать безопасный код, сохраняя при этом выразительность и околонулевые накладные расходы C++. В докладе будут подробно описаны механизмы языка, которые контролируют безопасность программы.

Хотя в данный момент Rust ещё не подходит для использования в продакшне, его всё равно стоит изучать. Во-первых, потому что это очень интересный подход к программированию, а во-вторых, потому что через несколько лет для разработки требовательных к ресурсам программ будет необходим именно Rust или другой похожий инструмент.


Ответ на: комментарий от Legioner

Ок, я понял о чём ты, я ступил. Но тогда возникает вопрос о применимости языка С для таких задач вообще. На лицо не правильно выбранный инструмент.

nanoolinux ★★★★
()
Ответ на: комментарий от tailgunner

как Haskell, если бы его писал человек, знающий C++ (и ничего кроме).

автор - окамльщик с довольно широким кругозором, у нынешней команды тоже довольно широкий кругозор

На самом деле действительно противоречия нет, если человек, обладающий знанием C++ (и ничего кроме) эквивалентен для написания человеку, обладающим знанием C++ (и ещё довольно широким кругозором). Эдакий страшный вирус мозга.

aedeph_ ★★
()
Ответ на: комментарий от ddos3

Свое мнение про такие обзоры я уже писал

И что, кого-то заинтересовало твоё мнение?

Manhunt ★★★★★
()
Ответ на: комментарий от aedeph_

На самом деле действительно противоречия нет

На самом деле Харпер считает, что на Rust повлиял SML. Так что ваши с Мигелем впечатления такие ваши.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

- Rust лучше, чем с++
- И чем он лучше?
- Чем с++

Безопасностью. Не будет больше битых указателей, не будет больше гонок при конкурентной работе с одним и тем же объектом, не будет больше неконсистентного state после неожиданной размотки стека, не будет больше утёкших ресурсов.

При управлении проектами в Серьезном Бизнесе ™, это означает существенное снижение трудозатрат и времени на багфикс. А их на багфикс, для справки, уходит больше, чем на собственно разработку. Именно ради сокращения времени на багфикс в моду введены всякие там юнит-тестирования и код-ревью.

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Не-не-не, я только с точки зрения логики и аксиоматики, мои впечатления не существуют вовсе.

aedeph_ ★★
()
Ответ на: комментарий от anonymous

в расте Тот Самый Баг в опенссл прошел бы незамеченным?

Он бы тупо не собрался. Хотя, зная разработчиков OpenSSL, код был бы завёрнут в unsafe чуть менее, чем полностью, так что никакой язык не помог бы.

quantum-troll ★★★★★
()
Ответ на: комментарий от umren

Меня интересует то, насколько go применим в качестве интрумента для разработки всяких приблуд в сфере DSP, в основном, аудио. Если go здесь неприменим, то может быть применим rust?

Hertz ★★★★★
()
Ответ на: комментарий от Hertz

Почему бы просто не написать что-нибудь небольшое и посмотреть?

quantum-troll ★★★★★
()
Ответ на: комментарий от anonymous

Скорее всего. От таких ошибок язык защитить не может в реальном проекте, ибо просто в случае надобности будет стоять unsafe, чтоб компилятор не мешал - «я знаю, что делаю». И бага сишная, а не крестовая. И код там - говно.

anonymous
()
Ответ на: комментарий от peregrine

Нет, неправильно. Главная проблема C++ в том, что он пытается поддерживать все парадигмы программирования, в результате разные программисты могут писать код принципиально разными методами, а язык богат фичами как ни один другой, отсюда и сложность.

Муаха. Муахаха. Муахахахахахах. Это ты про тот богатый фичами С++, в котором недолямбды поясились пару лет назад? Приоткрой для себя дверцу в таинственный мир какого-ть Common Lisp, детка.

xusrol
()

Ну в целом звучит занятно. Когда под него напишут фреймворк сопоставимый с glib, тогда будем пощупать.

xusrol
()
Ответ на: комментарий от anonymous

Там ужасный сишный код с указателями, memcpy и лапшой в коде. Тут никакой rust не спасёт.

anonymous
()
Ответ на: комментарий от xusrol

CL не умеет большую часть крестов. В свою очередь, его собственные прелести целиком завязаны на рантайм. Т.е. не нужны.

anonymous
()
Ответ на: комментарий от anonymous

ибо просто в случае надобности будет стоять unsafe, чтоб компилятор не мешал - «я знаю, что делаю».

Есть некоторая разница между unsafe'ом всюду и unsafe'ом в маленьком специально выделенном участке кода.

quantum-troll ★★★★★
()
Ответ на: комментарий от ozkriff

При чем тут веб? Увидел Яндекс и Мозиллу? :)

Очевидно, что язык будет затачиваться в первую очередь для бэк-эндов для веба.

xusrol
()
Ответ на: комментарий от xusrol

Функции как объекты там были со времён перегрузки operator(). А лямбды - это просто синтаксический сахар. И даже для них в крестах есть функциональность, которой нет больше не где - управление захватом. И это именно следствия поддержки парадигм, а не их дешовой, глючной и тормозной имитации на макросах, как в случае CL

anonymous
()
Ответ на: комментарий от xusrol

Очевидно

Если бы ты хоть немного подумал, тебе не было бы так «очевидно». Язык затачивается для разработки браузерного движка (servo), а это совсем другой тип ПО, не имеющий практически ничего общего с бек-эндами для веба.

quantum-troll ★★★★★
()
Ответ на: комментарий от quantum-troll

Ты код в openssl видел? Эти люди будут писать багнутый код на любом языке и будут затыкать компилятор, если понадобится. И да, там же не кресты.

anonymous
()
Ответ на: комментарий от quantum-troll

Удивительно, но кресты используются и для движков браузерных и для высоконагруженных бэкендов и для игр и для ещё чёрт знает чего... А вот «убийцы» не тянут конкуренцию даже в одной нише...

anonymous
()
Ответ на: комментарий от quantum-troll

Если бы ты хоть немного подумал, тебе не было бы так «очевидно». Язык затачивается для разработки браузерного движка

Если ты ты хоть немного подумал, ты бы понял, что у Яндекса нет своего движка. Rust разрабатывается с прицелом на клиент-серверные приложения, что в контексте Яндекса, очевидно, в первую очередь затачивать его будут под веб-бэкенды. И в любом случае и браузеры и бэк-енды это всё равно веб, про что шёл разговор изначально.

xusrol
()
Ответ на: комментарий от quantum-troll

Судя по тому как пилят servo, для браузерных движков rust вполне годен.

Оно уже активно конкурирует с другими браузерами при меньших трудозатратах? Или же оно покоится на гитхабе, бабло успешно пилится и до сих пор ни одного релиза не было?

xusrol
()
Ответ на: комментарий от anonymous

Функции как объекты там были со времён перегрузки operator().

И можно было в функции создать лямбду и вернуть её?

ugoday ★★★★★
()
Ответ на: комментарий от sf

сколько %?

А какая разница, сколько там процентов? Наличие или отсутствие зеленых потоков в твоей программе на эти проценты никак не повлияет, соответственно и говорить не о чем.

Переключение контекстов потоков интересно мерять в случае, когда потоки хоть немного друг с другом взаимодествуют

Лучше расскажи мне, как могут взаимодействовать зеленые потоки в rust на многоядерной машине. Почему их взаимодействие будет эффективнее, чем взаимодействие нативных потоков? Почему нативные потоки не могут взаимодействовать так же эффективно?

ddos3
()
Ответ на: комментарий от xusrol

Оно уже активно конкурирует с другими браузерами при меньших трудозатратах?

Там постепенно реализуют вещи, которые не существуют в других движках (вроде parallel layout, https://www.youtube.com/watch?v=nwI69Smjhx8 наглядно показывает, зачем это), и которые вряд ли когда-либо будут реализованы в существующих.

Или же оно покоится на гитхабе, бабло успешно пилится и до сих пор ни одного релиза не было?

Всё ещё в разработке, но уже сделано ОЧЕНЬ многое. Всё-таки не надо забывать, насколько сложны современные браузерные движки.

quantum-troll ★★★★★
()
Ответ на: комментарий от anonymous

Безопасностью

Отлавливание пары детских ошибок у вас называется безопасностью? Лол.

Во вселенной, которая расположена внутри твоего тесного черепа, программы никогда не падают с сегфолтом, инструментами типа memcheck/helgrind пользуются только дети, и тысячи долбоклюев в Крутых Фирмах не воссоздают из программы в программу сто лет как навязшую на зубах секурити дырку с переполнением буфера? Даже не знаю, чем тебе помочь... попроси своего психиатра подобрать менее отупляющие таблетки, что ли.

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Во вселенной, которая расположена внутри твоего тесного черепа, программы никогда не падают с сегфолтом

Есть мнение, что наркоман - это ты, а твои «безопасные языки» приводят больше к отжиранию ресурсов и отуплению разработчиков, чем повышению качества ПО.

xusrol
()
Ответ на: комментарий от xusrol

«безопасные языки» приводят больше к отжиранию ресурсов

В случае Rust, оверхеда во время исполнения на «безопасность» практически нет. Корректность программы доказывается компилятором во время сборки.

и отуплению разработчиков

Разработчики могут меньше думать о низкоуровневых проблемах с памятью, и больше — о собственно семантике того кода, который пишут. Это не отупление, а смещение фокуса внимания. Крайне полезное во всех отношениях.

Manhunt ★★★★★
()
Ответ на: комментарий от Hertz

После того как я пользовался полноценной DAW которая написана на Java, могу с уверенностью сказать, что Go вполне в теории применим :)

umren ★★★★★
()
Ответ на: комментарий от Manhunt

В случае Rust, оверхеда во время исполнения на «безопасность» практически нет.

Вот когда на нём что-то годное и законченное выйдет - тогда и посмотрим.

Разработчики могут меньше думать о низкоуровневых проблемах с памятью

Примерно это же я слышал про Java. И теперь у меня есть планшет, где всё почти на этой Java. Он тормозит и жрёт 600Мб RAM в простое после загрузки. И приложения в нём падают, падают чаще, чем, например, на моём серваке, где почти всё написано на старом как г-но мамонта С и после загрузки дюжины серверов отжирается 200Мб.

xusrol
()
Ответ на: комментарий от ddos3

> сколько %?

А какая разница, сколько там процентов? Наличие или отсутствие зеленых потоков в твоей программе на эти проценты никак не повлияет, соответственно и говорить не о чем.

TICK timer - 0.01% оверхеда на context switches (если задача хоть что-то делает на CPU).

Предлагаю идеальный тест для green threads - замер скорости context switch между тредами. Заодно и реальную стоимость task switch покажет.

С: прибиваем задачу гвоздём к первому CPU, стартуем 2 OS треда и переключаемся между ними 10 млн раз. Допустим, эмулируем ситуацию, они поочередно получают данные из сети, или ждут друг от друга сообщений:

// gcc -std=c99 -Wall -W -Wextra -O2 a.c -o a -pthread -ggdb3
#define _GNU_SOURCE

#include <sched.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

static void pin_to_cpu0 (void)
{
    cpu_set_t * cset;
    size_t cset_num = 1;
    cset = CPU_ALLOC(cset_num);
    size_t cset_size = CPU_ALLOC_SIZE(cset_num);

    CPU_ZERO_S(cset_size, cset);
    CPU_SET_S(0, cset_size, cset);

    sched_setaffinity (getpid (), cset_size, cset);
    CPU_FREE(cset);
}

static void * deed (void * arg)
{
    (void)arg;

    for (int i = 0; i < 5 * 1000 * 1000; ++i)
        pthread_yield ();
    return NULL;
}

int main()
{
    pin_to_cpu0 ();

    #define NUM_THREADS 2
    pthread_t ts[NUM_THREADS];
    for (int i = 0; i < NUM_THREADS; ++i)
        pthread_create (&ts[i], NULL /* attr */, &deed, NULL /* arg */);

    for (int i = 0; i < NUM_THREADS; ++i)
        pthread_join (ts[i], NULL /* ret arg */);

    return 0;
}
Запускаем (по несколько раз, для устоявшегося результата):
$ time ./a # чтобы примерное время одной операции прикинуть - надо на 10 млн делить

# не особый баян:
# Intel(R) Core(TM) i7-2700K CPU @ 3.50GHz
real    0m2.996s
user    0m0.152s
sys     0m2.837s

300 наносекунд на context switch, или в лаптях ~1000 тактов

# старик:
# AMD Athlon(tm) 64 X2 Dual Core Processor 4000+
# cpu MHz         : 2100.000
real    0m4.248s
user    0m0.391s
sys     0m3.799s

420 наносекунд, или ~900 тактов

# поганая эмбеддедщина:
# Feroceon 88FR131 rev 1 (v5l), в простонароде sheevaplug (armv5tel)
# BogoMIPS        : 1191.11 (это его примерная частота)

real    0m17.737s
user    0m0.880s
sys     0m16.600s

1773 наносекунд, или 1.7 микросекунды, или 2110 тактов.

Это чистый оверхед на context switch. Посмотрим (на i7), откуда ж он такой берется (будет немного врать, но интересно посмотреть общий смысл):

$ perf record ./a
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 0.556 MB perf.data (~24295 samples) ]
$ perf report
  22,86%  a  [kernel.kallsyms]   [k] __switch_to
   9,71%  a  [kernel.kallsyms]   [k] __schedule
   5,87%  a  [kernel.kallsyms]   [k] check_preemption_disabled
   5,34%  a  [kernel.kallsyms]   [k] _raw_spin_lock
   4,86%  a  [kernel.kallsyms]   [k] system_call
   4,01%  a  [kernel.kallsyms]   [k] rcu_note_context_switch
   3,06%  a  [kernel.kallsyms]   [k] put_prev_entity
   2,89%  a  [kernel.kallsyms]   [k] preempt_count_add
   2,83%  a  [kernel.kallsyms]   [k] __perf_event_task_sched_out
   2,68%  a  libc-2.19.so        [.] __sched_yield
   ... # страницей ниже появляется наша прога:
   0,29%  a  a                   [.] deed
   0,24%  a  [kernel.kallsyms]   [k] in_lock_functions
   0,24%  a  [kernel.kallsyms]   [k] rb_next
   0,16%  a  [kernel.kallsyms]   [k] update_rq_clock
   0,14%  a  a                   [.] pthread_yield@plt

[k] - время работы ядра

[.] - юзерспейса.

Что видим:

- как и ожидалось большинство времени программа живёт в task switch (__switch_to). В ядре это функция https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86...

Посмотрим, какой кусочек там ест больше всего (наводим на __switch_to, и " стрелка вправо").

Всего по чуть-чуть, но бросаются в глаза:

...
       │       wrmsr
 36,29 │145:   mov    %di,0x61c(%r12) ; программе плохо после свича. не знаю, какой именно это wrmsr
  3,54 │       mov    %r15d,%eax
...
       │       mov    %eax,%edx
       │       xrstor (%rdi)
 19,46 │     ↓ jmp    1f3 ; и после восстановления SSE/AVX
...
  0,15 │       xsave6 (%rdi)
 13,23 │       mov    0x680(%r12),%rax ; и после сохранения
  0,18 │       testb  $0x1,0x200(%rax)

Этого оверхеда можно избежать переключая потоки в юзерспейсе. Предлагаю эзотерический язык. Абишчаю, што дзелает то жэ самое:

-- ghc --make -O2 h.hs -o h
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Monad

main :: IO ()
main = do
    let n_threads = 2
    waits <- replicateM n_threads newEmptyMVar

    forM_ waits $ \w -> forkIO $ do replicateM_ (5 * 1000 * 1000) yield
                                    putMVar w ()
    forM_ waits takeMVar

Запускаем:

# всё на первом i7:
$ time ./h
real    0m0.475s
user    0m0.473s
sys     0m0.000s

50 наносекунд, 175 тактов

$ time ./h_th

real    0m0.552s
user    0m0.550s
sys     0m0.001s

55 наносекунд, 200 тактов

Позырим в perf, чем он там занят был:

$ perf record ./h
$ perf report

  39,06%  h  h                  [.] threadPaused
  22,30%  h  h                  [.] scheduleWaitThread
  11,09%  h  h                  [.] StgRunIsImplementedInAssembler 

В принцине не важно, что это.

Главное, что выхода в ядро нет. Всё время тратится в юзерспейс.

Сейчас понятно, откуда (на каких задачах) хотя-бы потенциально может взяться рост производительности?

Или всё равно в голове «зеленые треды - это ядерные + юзерспейс оверхед»?

Лучше расскажи мне, как могут взаимодействовать зеленые потоки в rust на многоядерной машине

Если с верхним понятно - отвечу :]

sf ★★★
()
Ответ на: комментарий от xusrol

И теперь у меня есть планшет, где всё почти на этой Java

В ведре dalvik, и язык похожий на жабу. Почти все стоковые приложения написаны на c.

Но самое смешное, ты и в правду думаешь что все твои падучие приложения хотя бы запустились, если бы их писали на С?

RedPossum ★★★★★
()
Последнее исправление: RedPossum (всего исправлений: 1)
Ответ на: комментарий от xusrol

И теперь у меня есть планшет, где всё почти на этой Java.

Если бы не Java, никакого планшета у тебя не было бы. Потому что разработать то же самое на Си стоит на порядок дороже, и тупо нерентабельно за те деньги, которые потребители готовы платить. Ты ещё на ассемблер с ручным распределением регистров подрочи.

Вот когда на нём что-то годное и законченное выйдет - тогда и посмотрим.

То есть по существу сейчас тебе сказать нечего?

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)

А, ну раз из яндыкса, то это наверняка опупеть какой авторитет, всем слушать и бояцца!

anonymous
()
Ответ на: комментарий от anonymous

Можешь выступить авторитетом лучше?

anonymous
()
Ответ на: комментарий от Manhunt

Если бы не Java, никакого планшета у тебя не было бы.

Maemo/Meego т.п. вполне себе реализовывали функционал сопоставимый.

xusrol
()
Ответ на: комментарий от ugoday

Не лямбду(которых тогда не было), а объект-функцию. Конечно можно, если решишь проблему видимости типа/функции(тем или иным способом) или вернешь объект базового класса. Лямбды из С++11 ничего тут не изменили - они просто создают анонимный объект анонимного типа. Функциональный объект(«функтор» в странной терминологии крестов, т.е. объект типа с operator()) от других объектов ничем не отличается.

Вот то, что это обобщили в std::function<прототип-функции> - хорошо. До этого была boost::function<прототип-функции> и др. реализации. Но это просто библиотечная обертка(в том числе и std::function - никакой магии там нет) над произвольным «исполняемым» объектом.

anonymous
()
Ответ на: комментарий от Manhunt

Во вселенной, которая расположена внутри твоего тесного черепа, программы никогда не падают с сегфолтом

Падают. Rust не поможет.

инструментами типа memcheck/helgrind пользуются только дети

Нет, они как раз полезны. А Rust не спасет.

и тысячи долбоклюев в Крутых Фирмах не воссоздают из программы в программу сто лет как навязшую на зубах секурити дырку с переполнением буфера?

Создают. И будут создавать на Rust. Они же долбоклюи. Лучше не пускать долбоклюев к разработке ПО. Жаль, что пока это не возможно =(

Отлавливаемые Rust'ом детские ошибки малополезны для долбоклюев. Долбоклюй поставит unsafe и будет писать как писал.

Компилятор мог бы помочь, но для этого нужны зависимые типы, вывод регионов и пр. клевые плюшки. Но пока это в зачаточном состоянии на практике.

anonymous
()
Ответ на: комментарий от Manhunt

Разработчики могут меньше думать о низкоуровневых проблемах с памятью, и больше — о собственно семантике того кода, который пишут.

Современный C++ вполне это позволяет. А те, кто на сишечке пишут - ССЗБ

anonymous
()
Ответ на: комментарий от quantum-troll

А это и есть регионы(насколько я вижу, подробно их в Rust не смотрел). Проблема в том, что они не выводятся, а их пишут руками. Алгоритмы вывода регионов есть для императивных языков и даже для ООП, но имеют ряд ограничений, на практике делающих их практически неприменимыми.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.