LINUX.ORG.RU

Почему Discord сменил Go на Rust. Блог разработчика.

 , ,


3

5

В статье автор описывает успешный проект Discord, в котором Rust используется для потоковой обработки в Go Live и их Elixir NIFs’ сервере.

Автор пишет
«Хочу отметить, что мы потратили очень мало усилий на оптимизацию реализации на Rust. Но даже только с базовой оптимизацией Rust оказался быстрее супероптимизированной реализации на Go. Это заметный плюс для Rust, показывающий, насколько легко писать эффективные программы, используя Rust, по сравнению с глубоким погружением в Go.»

>>> Why Discord is switching from Go to Rust

★★☆☆

Проверено: Shaman007 ()
Последнее исправление: cetjs2 (всего исправлений: 1)
Ответ на: комментарий от rmu

Статья от 4 февраля в новостях 7 марта? Серьёзно?

Причем, статья 2020 года. :3

X-Pilot ★★★★★
()
Последнее исправление: X-Pilot (всего исправлений: 1)
Ответ на: комментарий от Lrrr

Это аргумент о том что 100 раз уже обсуждали сраные индексы и тема была исчерпана. Чего ещё обсуждать?

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

Если компилятор вставляет проверки, за них придется заплатить производительностью.

Это где такой самостоятельный компилятор?

red75prim ★★★
()

Почему это в новостях? Статье больше года.

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

раст пока как-то не получил признания в с-нишах, а как вариант «на чем переписать боттлнэки нашего тормознутого бидон-проекта» иногда всплывает

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

Это просто дефолт такой. Конкретно для массивов можно делать одну из четырех вещей

  1. Ничего не делать. В многих случаях проверка вытирается, потому что компилятору очевидно что индекс не может выйти за пределы

  2. Писать в функциональном стиле или на итераторах, лишних проверок нету

  3. Использовать unsafe геттеры/сеттеры без проверок

  4. Ждать пока инопланетяне поделятся технологий безопасного доступа по индексу без лишних проверок если вариант 3 не подошёл. Возможно вариант 2 - это оно.

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

Эх, вот так пропустишь пару новомодных технологий - и даже не пригоришь как следует на ЛОРе. Вот так и приходит старость :-/

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

Ну у нас понятно не было кобола, а шарпом заменяли даже и не дельфи, а внезапно C++. Ещё и стали сайты делать на асп.нет. Вот это был хайп что надо.

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

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

Ну хоть не зюксель.

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

Вы просто сами себе придумали определение Zero cost abstraction и сами с ним спорите. И, по всем видимости, ваше определение не совпадает с тем что разработчики Rust называют Zero cost abstraction.

Zero cost abtraction означает всего лишь, что если бы вы писали код вручную, не пользуясь это абстракцией, вы не смогли бы написать более эффективный код, чем вам сгенерит компилятор из этой абстракции. Пример Zero cost abstraction это async/await функции. Это не означает что async/await не требует доп. процессоного времени и не аллоцирует. Это означает, что если бы вы, вместо того чтобы написать async fn my_func() взяли и вручную реализовали бы state machine вокруг ивент лупа, у вас бы получился ровно такой же код, как вам сгенерит компилятор из async fn my_func()

Цитируя статью на эту тему:

there are two factors that make something a proper zero cost abstraction:

No global costs: A zero cost abstraction ought not to negatively impact the performance of programs that don’t use it. For example, it can’t require every program carry a heavy language runtime to benefit the only programs that use the feature.
Optimal performance: A zero cost abstractoin ought to compile to the best implementation of the solution that someone would have written with the lower level primitives. It can’t introduce additional costs that could be avoided without the abstraction.
e-max
()
Ответ на: комментарий от Ford_Focus

На жести тормозной он написан на какой-то точно. Один раз запустил зарегаться, вспоминать не хочется. Все знакомые по разным мессенджерам, спасибо pidgin’у, весь этот зоопарк можно в одно окно запихнуть. Не понимаю, как живут люди, у которых штук по 5 месседжеров на телефоне, как они не путаются-то, где у них кто

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

На жести тормозной он написан на какой-то точно. Один раз запустил зарегаться, вспоминать не хочется.

электрон сэр

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

Зато теперь программистом может стать каждый!

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

Если да, то как можно сравнивать компилятор с интерпретатором?

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

Лисп машины

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

Это абстрактная теория, к реальности никак не относящаяся. В реальности ручной код на ассемблере будет тормозной

В реальности как раз получается наоборот, любой более менее крупный проект на асемблере - быстрый и компактный. Трудоёмкость - да, всё остальное выдумки.

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

Если СНИПы нарушаются, значит дом некачественный.

Фейсплам. Зачем сравнивать несравнимое. Ты можешь себе в коробку 5х5м проложить СИП 3х50, и включать там лампочку с чайником. Нарушил ты СНИП ? Нет. Дал*аёб ли ты ? Да.

Если СНИПы не нарушаются, значит есть большие шансы, что стройка ведётся качественно.

СНИПы везде нарушаются, можешь лично меня пригласить на любой объект строящийся, я найду там нарушение СНИПов. Все стройки некачественные?

А у программистов никаких СНИПов нет.

Логично, а ещё у автомобилистов должны быть права на вождение, а программисты не сдают на права для программирования !

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

Go, Rust… Зачем всё это, когда есть простой и удобный C++?

Зачем ложка и вилка, когда есть ладонь. Ей даже можно жопу подтирать, а ты вилкой можешь это делать? Нет. Ладонь лучше.

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

Фейсплам. Зачем сравнивать несравнимое. Ты можешь себе в коробку 5х5м проложить СИП 3х50, и включать там лампочку с чайником. Нарушил ты СНИП ? Нет. Дал*аёб ли ты ? Да.

Не долбоёб, а просто транжира. Что плохого в 3x50?

СНИПы везде нарушаются

Нет.

можешь лично меня пригласить на любой объект строящийся, я найду там нарушение СНИПов.

Устраивайся инспектором, много денег будешь зарабатывать, раз ты такой знающий.

Все стройки некачественные?

Не все. Но те, где нарушаются СНИПы, с большой вероятностью некачественные. Исключения бывают, когда архитектор (а не строители) намеренно нарушает СНИПы с полным пониманием того, что он делает. Но это редкость.

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

Ты читать вообще умеешь? Великим и могучим написано:

The service we switched from Go to Rust is the “Read States” service. Its sole purpose is to keep track of which channels and messages you have read. Read States is accessed every time you connect to Discord, every time a message is sent and every time a message is read. In short, Read States is in the hot path. We want to make sure Discord feels super snappy all the time, so we need to make sure Read States is quick.

«Сервис который мы перевели с Го на Раст называется «Статусы прочитано». Единственное его назначение это трекать какие каналы и сообщения вы уже прочитали….»

Распилить на микросервисы .ля….

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

Типичная подмена понятий. Не путайте ANSI C89 и современный C++. Последний к кросплатформенному ассемблеру имеет уже мало отношения, если только не писать на нём в стиле Си, а писать как положено с STL и шаблонами во все места.

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

Не долбоёб, а просто транжира. Что плохого в 3x50?

Примерно то-же, что заливать стены толщиной 10м в двух этажном доме из соображений несущей способности.

В 3х50 ничего плохого нет, как собственно и ничего хорошего примирительно к обычному загородному дому.

Устраивайся инспектором, много денег будешь зарабатывать, раз ты такой знающий.

В том то и дело, что в реальной жизни никому не нужны подобные эксПерды. Большинство строительных норм и правил, будут нарушены в любом случаи, и не из-за халатности, а просто из-за объективных обстоятельств.

Вот тебе пример, ты решил в квартире сделать проводку, в новостройке. Стены монолит. По правилам ты не имеешь права штробить глубже 250мм, и длинной более 3м.

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

Так, что никаких тебе проходных выключателей. А вдруг у тебя есть варочная панель или духовой шкаф? Решил ты в гофре проложить трёхфазный кабель на 4-6кв.мм. Вот незадача, опять не вписываешься.

А если стена длинней 3м ?

Не все. Но те, где нарушаются СНИПы, с большой вероятностью некачественные. Исключения бывают, когда архитектор (а не строители) намеренно нарушает СНИПы с полным пониманием того, что он делает. Но это редкость.

Нет ни одного строительного сооружения где ни один СНИП не был нарушен, это факт.

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

Ты читать вообще умеешь? Великим и могучим написано:

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

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

Не можешь штробить - не штроби, не понимаю проблему. Ставь наружние розетки. Провода вообще ведут по потолку и опускают с потолка вниз, если по уму делать и прятать, три метра тут за глаза.

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

Ставь наружние розетки.

И что, много видел современных квартир с наружными розетками?

Провода вообще ведут по потолку и опускают с потолка вниз, если по уму

Ум здесь не при чём. Если потолок подвесной (кгл, натяжной и тд), то такой вариант возможен.

Если потолок под покраску, лепнина и тд, то нет. Пол зачастую в новых домах залит уже от застройщика.

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

если по уму делать и прятать, три метра тут за глаза.

Сделать можно, что угодно. Можно вообще в кабель каналах поверх итальянских обоев за 30к.рулон проводку проводить, по СНИПам ? Да.

Ты для начала мне покажи в новостройках кто накладные розетки ставит, кроме разве что совсем бедных семей ?

А распред встроенный тоже глумление над СНИПами ? У себя от застройщика железный накладной оставил?

shpinog ★★★★
()

А тем временем в Debian потихоньку запихивают coreutils переписанный на rust.

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

весь vvoip у дискорда это webrtc - сложная, большая плюсовая либа… а чатики и прочее можно на чем угодно писать

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

На твой взгляд - что за самая важная штука в расте в сравнении с цпп?

На мой взгляд: бороу чекер и явный unsafe.

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

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

уж сколько раз твердили миру, что тупые проверки на границы массива при доступе по индексу - это нифига не zero cost.

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

А расставленные вручную непонятно кем unsafe и impl Send - это нифига не «помощь компилятора».

Это тоже передёргивание. Да, компилятор ориентируется на Send/Sync маркеры, но это и позволяет писать свой код, который будет работать по тем же правилам. Можно там налажать? Конечно, как и везде. Вот только пользователь может взять проверенную (или даже стандартную) библиотеку и не париться об этом. Или можно минимизировать unsafe и обложить его тестами и, опять же, не напрягаться в остальном коде.

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

На мой взгляд: бороу чекер и явный unsafe.

clang-tidy? Честно, я даже пару статей на хабре пролистнул. Вот хз, у меня вообще складывается ощущение (возможно ошибочное), что главный аргумент везде - смотрите, в плюсах new/delete, забыл/утекло, голые указатели. И все старательно не замечают наличие нормальных умных указателей уже целых 10 лет. Если кто-то так помешан на безопасности, то достаточно сделать для проекта:

$ grep -R '\bnew\b' *

И за любое использование без причины бить по рукам. Для всего остального - vector.push(), make_unique(), make_shared(). 90% всех предъяв к цпп исчезнет моментально. Не выходит как-то проникнуться.

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

Поддержу. В плюсах RAII - уберфича. Не надо никаких лишних александреску с метапрограммировнием в коде. Но и отказываться от базовых механизмов не надо. И будет чистенько и довольно безопасно.

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

Кстати, а раст для безопасности запрещает арифметические операции в сейф коде? Делить опасно - можно на ноль разделить. Кастовать дабл в целое - можно не влезть в границы, +-* - целочисленное преполнение. Их же цпп не от вредности сделал ЮБ, там зависимость от архитектуры должна быть. Но безопасный раст таким путем ведь пойти не может, он же не цпп какой-нибудь.

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

90% всех предъяв к цпп исчезнет моментально. Не выходит как-то проникнуться.

Инвалидация итераторов, атомики даже при однопоточном использовании shared_ptr, data races - это в 10%?

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

Инвалидация итераторов

Для libstdc++ есть замечательный дефайн -D_GLIBCXX_DEBUG, после этого начнешь отлавливать невалидные итераторы в отладочном режиме. Можешь проверить

#include <iostream>
#include <vector>
using namespace std;

int main() {
	vector<int> v = {1,2,3,4};
	auto p = v.begin();
	for (int i = 0;  i < 500;  ++ i)
		v.push_back(5);
	cout << *p << endl;
}

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

атомики даже при однопоточном использовании shared_ptr

Какие там проблемы?

data races

Я в растомногопоток не окунался сильно, понял лишь то что он запретил разделяемые, изменяемые данные настроив там какие-то механизмы (тут вопрос по стоимости еще надо прояснить).

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

хотя плохо себе представляю как такой говнокод можно написать

А почему к new такая логика не применима? Прогнал через MSAN и спи спокойно.

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

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

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

Атомики в shared_ptr control block в однопоточном режиме не нужны (падение производительности), но никаких средств разделить многопоточный и однопоточный доступ в C++ нет. Указатель в shared_ptr - не атомик, но это больше про data races.

И раст не запрещает, а заставляет ставить табличку мокрый пол unsafe.

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

Атомики в shared_ptr control block в однопоточном режиме не нужны (падение производительности), но никаких средств разделить многопоточный и однопоточный доступ в C++ нет.

Ну тоже мне катастрофа, я не уверен, что ты много выйграешь в итоге, стоит ли плодить сущности в стд, спорно. Но свой шптр накостылить ведь 5 минут, там же никакой магии.

Указатель в shared_ptr - не атомик

Там и class Shared_data не атомик, сами синхронизируем ведь.

И раст не запрещает, а заставляет ставить табличку мокрый пол unsafe.

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

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

никаких средств разделить многопоточный и однопоточный доступ в C++ нет

да с чего бы? Нет никаких проблем запилить создающую потоки библиотеку, которая будет принимать только структуры, обмазанные специальными тегами.

Смешно смотреть, как в одном ограниченном недоязыке сначала запилили какую-то не особо кому нужную фичу на уровне компилятора, потому что в этом недоязыке тупо нет возможностей реализовать ее на уровне библиотек, и потом начали рекламировать ЭТО как некую уникальную возможность, отсутствующую в С++ и т.п.

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

В случае с многопотоком - именно запрещает, предлагая какие-то свои синтетические механизмы

Предлагает атомики, мутексы и rw-lock’и. Ну и возможность безопасного параллельного доступа к структуре данных из разных потоков индицируется маркерным трейтом Sync. Так что в safe Rust запрещается только несинхронизированное параллельное изменение данных, то есть data races.

В unsafe контексте есть неограниченные возможности использовать мутабельный алиасинг с помощью UnsafeCell и *mut указателей с неизбежной возможностью нарваться на UB, естественно.

red75prim ★★★
()

Почему разработчики на rust не поддерживают mercurial? Ведь это самая популярная и хотя бы используемая vcs, написанная в том числе частично на rust? Там что-то собирается им опционально.

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

Можешь показать на примере? Как это закостылить на расте:

#include <thread>
#include <iostream>
#include <shared_mutex>
using namespace std;

class S {
	shared_mutex mtx;
	unsigned i = 0;
public:
	unsigned sh_fn() {
		shared_lock lck{mtx};
		return i;
	}
	void uq_fn() {
		lock_guard lck{mtx};
		++ i;
	}
}s;

int main() {
	thread r{[](){
		while (true)
			cout << s.sh_fn() << endl,  this_thread::sleep_for(1s);
	}};
	thread r2{[](){
		while (true)
			cout << s.sh_fn() << endl,  this_thread::sleep_for(1s);
	}};
	thread w{[](){
		while (true)
			s.uq_fn(),  this_thread::sleep_for(1s);
	}};
	r.join(), w.join(), r2.join();
	return 0;
}
pavlick ★★
()
Последнее исправление: pavlick (всего исправлений: 1)
Ответ на: комментарий от red75prim

ну полюбуйтесь, просто картина маслом. Придурок, в свое время ответивший мне «раст не может оптимизировать выражения вида x*2/2, потому что эта оптимизация некорректна», сейчас выдает вот такое.

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

Не надо так напрягаться. С++ теперь тоже не может: знаковое переполнение теперь там не UB, а two’s complement, как в расте.

На всякий случай уточню. Не может оптимизировать x*2/2 в x, для знаковых целых.

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

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0632c744c9ab877d2bd1c8f6dc3e20f5

use lazy_static::lazy_static;
use std::thread;
use std::time::Duration;

mod foo {
    use std::sync::Mutex;

    pub struct S {
        i: Mutex<u32>,
    }

    impl S {
        pub fn new() -> S {
            S { i: Mutex::new(0) }
        }
        pub fn sh_fn(&self) -> u32 {
            *self.i.lock().unwrap()
        }
        pub fn uq_fn(&self) {
            let mut guard = self.i.lock().unwrap();
            *guard += 1;
        }
    }
}

use foo::S;

lazy_static! {
    static ref SYNC: S = S::new();
}

fn main() {
    let r1 = thread::spawn(|| {
        for _ in 0..10 {
            println!("{}", SYNC.sh_fn());
            thread::sleep(Duration::from_millis(10));
        }
    });
    let r2 = thread::spawn(|| {
        for _ in 0..10 {
            println!("{}", SYNC.sh_fn());
            thread::sleep(Duration::from_millis(10));
        }
    });
    let w = thread::spawn(|| {
        for _ in 0..10 {
            SYNC.uq_fn();
            thread::sleep(Duration::from_millis(10));
        }
    });
    r1.join().unwrap();
    r2.join().unwrap();
    w.join().unwrap();
}
red75prim ★★★
()
Ответ на: комментарий от red75prim

Спс. Поковыряю для общего развития. Какой тяжелый синтаксис, цпп просто лаконичная конфетка.

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

Менеджер пакетов же. Не надо пытаться сбоку привернуть сторонние поделки, которые поддерживает полтора землекопа.

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