Опубликован (https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html) релиз языка системного программирования Rust 1.37 (http://www.rust-lang.org), основанного проектом Mozilla. Язык сфокусирован на безопасной работе с памятью, обеспечивает автоматическое управление памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime.Автоматическое управление памятью в Rust избавляет разработчика от манипулирования указателями и защищает от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo (http://blog.rust-lang.org/2014/11/20/Cargo.html), позволяющий получить нужные для программы библиотеки в один клик. Для размещения библиотек поддерживается репозиторий crates.io (https://crates.io/).
Основные новшества (https://github.com/rust-lang/rust/blob/master/RELEASES.md#ve...):
- В пакетный менеджер Cargo интегрирована команда "cargo vendor", ранее поставляемая в виде отдельного пакета (https://github.com/alexcrichton/cargo-vendor). Команда позволяет организовать работу с локальной копией зависимостей - после выполнения "cargo vendor" все исходные тексты зависимостей проекта загружаются с crates.io в локальный каталог, который затем можно использовать для работы без обращения к crates.io (после выполнения команды показывается подсказка по изменению конфигурации для использования каталога при сборках). Указанная возможность уже применяется для организации поставки компилятора rustc с упаковкой всех зависимостей в один архив с релизом;- Появилась возможность создания ссылок на варианты перечислений (enum), используя псевдонимы типа (например, в теле функции "fn increment_or_zero(x: ByteOption) можно указывать "ByteOption::None => 0"), конструкции вычисления типов (‹MyType‹..››::вариант => N) или обращения Self (в блоках c &self можно указать "Self::Quarter => 25");
- Добавлена возможность создания неименованных констант в макросах. Вместо определения имени элемента в "const" теперь можно использовать символ "_" для динамического выбора неповторяющегося идентификатора, позволяющего избежать конфликта имён при повторном вызове макроса;
- В компиляторе rustc обеспечена (https://doc.rust-lang.org/rustc/profile-guided-optimization....) поддержка оптимизации на основе результатов профилирования кода (PGO, Profile-Guided Optimization),
позволяющиъ генерировать более оптимальный код на основе анализа статистики, накопленной в процессе выполнения программы. Для генерации профиля предусмотрен флаг "-C profile-generate", а для использования профиля при сборке - "-C profile-use" (вначале программа собирается с первым флагом, обкатывается и после создания профиля собирается повторно со вторым флагом);
- При выполнении команды "cargo run", которую удобно использовать для быстрого тестирования консольных приложений, добавлена возможность автоматического выбора исполняемого файла для запуска, в случае если в пакете присутствует несколько исполняемых файлов. Выполняемый по умолчанию файл определяется через директиву default-run в секции [package] с параметрами пакета, которая позволяет обойтись без явного указания имени файла через флаг "--bin" при каждом запуске "cargo run";
- Добавлена возможность использования атрибута "#[repr(align(N))" с перечислениями (enums), используя синтаксис, аналогичный определению структуры AlignN‹T› с выравниванием и последующему использованию AlignN‹MyEnum›;- В разряд стабильных переведена новая порция API, в том числе стабилизированы методы BufReader::buffer, BufWriter::buffer,
Cell::from_mut,
Cell::as_slice_of_cells,
DoubleEndedIterator::nth_back,
Option::xor,
{i,u}{8,16,64,128,size}::reverse_bits, Wrapping::reverse_bits и
slice::copy_within.Дополнительно можно отметить начало тестирования (https://async.rs/blog/announcing-async-std/) проекта Async-std (https://github.com/async-rs/async-std/), предлагающего асинхронный вариант стандартной библиотеки Rust (порт библиотеки std, в котором все интерфейсы предложены в версии с async и готовы для использования с синтаксисом async/await).
URL: https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html
Новость: https://www.opennet.dev/opennews/art.shtml?num=51302
Хорошечно!
Так-то аналогов Раста фактически нет. Хочется zero cost abstraction и скорости плюсов? И чтоб популярный за пределами круга чей-то мамы?
Ну и кто кроме него?
А синтаксис вырвиглазный только до того момента, пока не начинаешь его понимать. Сам через это прошел.
Расскажи кстати какой полезный сервис ты написал или даже внедрил на расте?
Я например написал около 6-ти инструментов, серьёзно упрощающие работу. Четыре из них для работы с логами. Logmerge - мержит тысячи логов в один файл сохраняя записи в хронологическом порядке и корректно обрабатывая многострочные записи, типа стектрейсов. Изначально тулза была на жаве. Отрабатывала за 25 минут и съедала 2500 мегов памяти. На расте те же данные за 1 минуту и съедает 3 мегабайта памяти.
какой в ж.. sed awk в венде? На вас краснглазых мир клином не сошелся!
Этих вполне достаточно. Или можно руками собрать.http://gnuwin32.sourceforge.net/packages/gawk.htm
http://gnuwin32.sourceforge.net/packages/sed.htm
На знаю что там была за удалённая нить, но вообще сед и авк в винде норм. BusyBox называется. Я так кросс-платформенные скрипты делаю. И не для себя, а для гигантских компаний по всему миру.
«zero cost abstraction» - это случайно не из методичек по Расту?
Я вот не знаю, хочется ли мне этого, т. к. не знаю, что это такое ;)> А синтаксис вырвиглазный только до того момента, пока не начинаешь его понимать.
То есть этот момент может не наступить никогда?))
Это ещё из методичек по C || C++ :)
Например, заменяешь цикл расчета суммы до аналогичной функций в одну строку с лямбдой (типа как map/reduce)
C++/Rust не это потратят столько же мс, сколько и обычный цикл (условные 20 мс). В других языках может потратиться на несколько сотен больше мс (500, к примеру)> То есть этот момент может не наступить никогда?))
У меня наступил почти сразу после нескольких лекций с ютубчика)
В Расте довольно неплохой синтаксис, пускай и загружен управлением памятью
Но в тех же плюсах есть моменты и похуже
Каждому свое - не думаю, что в Лиспе есть накладки с лямбдами нопример.
Шта?
В лиспе есть очень интересные "накладки". Скажем в lisp'е нет понятия "переменная" в смысле других языков. Там есть символы. Символ может иметь значение, и таким образом его можно использовать как переменную. Но согласно семантике лиспа, каждая ссылка на символ должна разрешаться начиная с имени этого символа в рантайме. Да, всякие там оптимизирующие компиляторы могут обратить внимание на то, что внутри (let ((x 0)) ...) x -- это локальная переменная, и они могут даже не создавать символ с именем x в некоторых случаях, заменив его регистром. Но, как говориться, шаг влево, шаг вправо, и вот у тебя уже создан символ x, и обращение к нему неявно включает в себя поиск в хештабличке.Но там есть и "накладки" с лямбдами. Функция в lisp'е это значение, которое (если копнуть в сторону реализации), располагается в куче, сопровождается тегом типа, а код жонглирует указателем на кусок памяти в функцию. А указатель не простой, динамическая типизация требует встроить в указатель тег типа (все возможные типы закодировать в указателе не удастся, поэтому там несколько бит под этот тег, самые частовстречающиеся типы полностью кодируются этими битами в указателе, в остальных эти биты выставлены в определённое значение, говорящее о том, что тип объекта определять надо по тегу прицепленному к объекту), и в дополнение к этому тегу типа в указателе есть ещё бит для сборщика мусора. И вот мы уже получаем, что у нас выравнивание объектов не менее восьми байт (а то и 16-32), потому что несколько бит указателя используются не для того, и кроме того, разадресация указателя требует выделения этих битов, сверки с ними, доведения указателя до машинного вида (обнуление всех посторонних битов), и только после этого разадресация. Это касается не только лямбды, но и её это касается тоже.
Но это лишь полбеды, лисп имеет такую фичу как lexical binding, которую очень любит, скажем, Столлман. Фишка в том, что функция может ссылаться на глобальный символ, но при помощи блока let, я могу переопределить значение этого символа на время выполнения блока let. И таким образом, я могу переопределить значение глобального символа, вызвать функцию, ссылающуюся на этот символ, и она из этого символа получит подставленное мною значение. А в соседнем потоке выполнения, та же функция вызванная без блока let, получит исходное значение.
В lisp'е такого рода накладных расходов, дофига. И они не бесплатны для программы, даже если она не использует всякие фичи типа lexical binding, сборку мусора, динамическую типизацию и тп.
Все вами описанное в личпе как раз и является "zero cost", так как реализовано естественным для рантайма образом.Выравнивание объектов в памяти по границе слова (двойного слова)? Любой язык, кроме специально оговоренных программистом случаев, это делает за вас - напомню, что обращение к невыровненным словам до сих пор влечет за собой CPU пенальти. А в лиспе (и других языках со сборкой мусора) это выравнивание дополнительно используется для элегантного 0-cost выделения объектов в куче, где выделение объекта, это просто увеличение внутреннего указателя на N слов.
Локальные переменные? Локальные "переменные" еще на этапе компиляции переименовываются в вида lvarNNNNN и не требуют поиска по таблице, так как даже студенческие лисп-поделки умеют это дело опитимизировать.
В общем зря вы на лисп так - в своей области, где важен высокий уровень абстракции и хороший математический вкус лисп все еще отлично выглядит: элегантный, быстрый, абстрактный. Настолько отлично, что его каждый раз пытаются переизобрести в качестве подмножества того или иного языка (десятое правила Гринспена, да).
> Все вами описанное в личпе как раз и является "zero cost", так
> как реализовано естественным для рантайма образом.
> Выравнивание объектов в памяти по границе слова (двойного слова)? Любой язык, кроме
> специально оговоренных программистом случаев, это делает за вас - напомню, что
> обращение к невыровненным словам до сих пор влечет за собой CPU
> пенальти.К невыравненным байтам тоже пенальти? А в lisp'е байт будет занимать четыре а то и восемь байтов памяти. И будут огромные проблемы сделать упакованный массив байтов или упакованную структуру, потому что будут огромные проблемы со ссылками на эти упакованные байты.
> А в лиспе (и других языках со сборкой мусора) это
> выравнивание дополнительно используется для элегантного 0-cost выделения объектов в куче,
> где выделение объекта, это просто увеличение внутреннего указателя на N слов.Куча -- это не zero-cost абстракция. Она отъедает процессорное время и изменяет объём расходуемой памяти, причём как именно она будет это делать зависит от реализации этой кучи. Но что самое интересное, ты будешь платить за кучу, вне зависимости от того, хочешь ты её использовать или нет. malloc/free в этом смысле -- это вещь не бесплатная, но если ты их не используешь, ты их не используешь и не платишь за их использование.
> Локальные переменные? Локальные "переменные" еще на этапе компиляции переименовываются
> в вида lvarNNNNN и не требуют поиска по таблице, так как
> даже студенческие лисп-поделки умеют это дело опитимизировать.А если эта локальная переменная не локальна?
> В общем зря вы на лисп так - в своей области, где
> важен высокий уровень абстракции и хороший математический вкус лисп все еще
> отлично выглядит: элегантный, быстрый, абстрактный.Элегантность спорна, абстрактность бесспорна. А вот быстрота в lisp'е достигается огромными геморроями, и то не во всех. Если lisp позволяет аннотации типов переменных функций, если он позволяет выделять память на стеке, если он позволяет работать с машинными типами, то тогда на нём можно писать быстрые программы. Но пока ты будешь это делать, ты поймёшь, что элегантность lisp'а выходит боком. Lisp не для написания быстрых программ, он для быстрого написания программ, которые ты не знаешь заранее как писать. Для тех проблем, которые ты исследуешь "боем" посредством написания программы.
> Настолько отлично, что его каждый
> раз пытаются переизобрести в качестве подмножества того или иного языка (десятое
> правила Гринспена, да).Ну естественно. Если в язык засунуть всё, то любой другой язык будет его подмножеством. Но засунуть всё -- это очень дорогостоящая вещь. Можно вспомнить историю PL/1. Ещё ты можешь почитать документацию на ANSI Common Lisp. Если от чтения просветления не возникнет, то попробуй взять sbcl и написать на нём что-нибудь. Когда в язык пихают всё на все случаи жизни, это кончается плохо. Jack of all trades, master of none. Он может всё, но сливает любому более специализированному языку в области его специализации. То есть для любой проблемы можно найти более подходящий язык, нежели lisp.
> Скажем в lisp'е нет понятия "переменная" в смысле других языков. Там есть символы.Вообще-то сравнивать символ с переменной не корректно. Наиболее близким аналогом переменной в лиспах является связывание.
> Но это лишь полбеды, лисп имеет такую фичу как lexical binding
> <...>
> таким образом, я могу переопределить значение глобального символа, вызвать функцию, ссылающуюся на этот символ, и она из этого символа получит подставленное мною значениеТы путаешь с динамическим связыванием. Динамическое связывание -- это во-первых зло, а во-вторых диалекты scheme (которые таки да, тоже обычно подразумеваются, когда мы говорим о lisp) его либо вообще не поддерживают, либо поддерживают через явное декларирование в каждом месте, где используются, что это не лексические связывания. Как пример можешь посмотреть на parameters в Racket.
>> Скажем в lisp'е нет понятия "переменная" в смысле других языков. Там есть символы.
> Вообще-то сравнивать символ с переменной не корректно. Наиболее близким аналогом переменной
> в лиспах является связывание.Может быть. Попробуй объяснить человеку далёкому от lisp'а эти нюансы.
> Ты путаешь с динамическим связыванием.
Может быть.
> Динамическое связывание -- это во-первых зло,
Да ладно. Я не считаю себя фанатом динамического связывания, но это очень удобная фишка.
> во-вторых диалекты scheme (которые таки да, тоже обычно подразумеваются, когда мы
> говорим о lisp) его либо вообще не поддерживают, либо поддерживают через
> явное декларирование в каждом месте, где используются, что это не лексические
> связывания. Как пример можешь посмотреть на parameters в Racket.Да, я знаю. Поэтому моя попытка освоить схему с ракетом закончилась неполным чтением вводной документации. Нахрен нужен лисп без динамического связывания? Можно ещё lisp без скобок сделать, можно сделать lisp без макросов. Можно вообще получить в результате ruby. Но зачем?
>> Ты путаешь с динамическим связыванием.
> Может быть."Может быть". =/
>> Динамическое связывание -- это во-первых зло,
> Да ладно. Я не считаю себя фанатом динамического связывания, но это очень удобная фишка.Скажем так, у него и правда есть область применения. Тем не менее, в CL "ушки" таким символам ставят не просто так, а как раз потому, что именно этим способом большинство лисперов отстреливают себе ноги.
Не знаю, как в C++, но в C нет никаких zero cost abstractions, по причине отсутствия каких либо абстракций.
В C++ есть. Дырявые. Потому и zero cost.
В C есть абстракции, если ты их не видишь, то это значит, что ты не кодил на ассемблере. Возьмём, скажем, понятие "переменная". В ассемблере такого понятия, по-хорошему, нет. Там есть регистры, есть стек, есть RAM. И ты перекладываешь значения с места на место. Некоторые места в RAM могут иметь вполне определённую семантику, и такие места можно назвать переменными, но подчастую работа с этими переменными сводится к тому, чтобы забрать оттуда значение, что-то с ним сделать, положить обратно. В C же, переменная -- это переменная, она может располагаться на стеке, в куче, в статической памяти, в регистре, иногда это определяется контекстом, но очень часто компилятор за тебя решает, когда и какая переменная будет представляться регистром, а когда ячейкой стека.А типы? В асме нет типов, тип значения определяется операцией, которую ты выполняешь. Если add -- это целочисленное сложение 32-х битных целых, то она будет складывать 32-х битные флоаты как целые числа. В C тип определяется типом переменной или другого источника/приёмника откуда ты берёшь или куда ты кладёшь значение. Если ты используешь операцию + для сложения целых, то она сложит целые. Если ты используешь её для сложения float'ов, она сложит флоаты. При этом при необходимости типы аргументов будут приведены до соответствия друг-другу. Особенно эти сишные типы заметны на указателях: для асма нет разницы между целым значением, void* и char*. Ты когда пишешь на асме думаешь об указателях как о целых числах. В C же, указатель с некоторой натяжкой можно назвать целым числом, но в зависимости от типа указателя операция сложения будет выдавать разные значения. (char*)0 + 1 даст 1, а (int*)0 + 1 даст 4.
В C есть функции -- это тоже абстракции. В ассемблере есть код и есть данные, деление между ними условно -- ты можешь сделать jmp на данные, или прочитать байт кода в регистр. В асме ты можешь создавать функции, но при этом ты можешь сделать call в середину функции, или jmp из одной функции в другую. И, я отмечу, это не всегда глупость, это может быть вполне осмысленным и полезным действием. Скажем, tail call'ы так и делаются -- вместо call func/ret, мы делаем jmp func. Функции с несколькими точками входа тоже не редкость в асме.
Абстракции есть в любой проблеме, о которой ты в состоянии думать. Если ты не видишь этих абстракций, значит ты недостаточно глубоко копнул.
>[оверквотинг удален]
> что ты не кодил на ассемблере. Возьмём, скажем, понятие "переменная". В
> ассемблере такого понятия, по-хорошему, нет. Там есть регистры, есть стек, есть
> RAM. И ты перекладываешь значения с места на место. Некоторые места
> в RAM могут иметь вполне определённую семантику, и такие места можно
> назвать переменными, но подчастую работа с этими переменными сводится к тому,
> чтобы забрать оттуда значение, что-то с ним сделать, положить обратно. В
> C же, переменная -- это переменная, она может располагаться на стеке,
> в куче, в статической памяти, в регистре, иногда это определяется контекстом,
> но очень часто компилятор за тебя решает, когда и какая переменная
> будет представляться регистром, а когда ячейкой стека.Вообще опыт программирования на ассемблере вполне себе имею и до сих пор приходится периодически или писать ассемблерные вставки для C, а то и чисто ассемблерный код для 86-ой архитектуры, или смотреть дизассемблированный код. Ассемблер даёт возможность объявлять именованные ячейки памяти - на самом деле метки присвоенные ячейкам. По крайней мере для 86 архитектуры, как для для разных там masm-ов/tasm-ов, так и для разных gas-ов это справедливо. Опять-же для tasm-ов была возможность даже объявлять переменные на стеке в соответствии с определённой callcing convention, и тогда написав что-то типа
mov ax,myparam1
в коде можно было получить что-то типа:
mov ax,[bp + 7]Так-что ассемблер ассемблеру рознь - некоторые даже позволяли объявлять структуры и прочие высокоуровневые абстракции.
А вообще в C, как и в ассемблере приходится явно заявлять класс хранения переменной. И даже намекнуть компилятору, что было-бы неплохо вот эту переменную хранить в регистре, ну а он может с этим согласиться, а может и нет.
> А типы? В асме нет типов, тип значения определяется операцией, которую ты
> выполняешь. Если add -- это целочисленное сложение 32-х битных целых, то
> она будет складывать 32-х битные флоаты как целые числа. В C
> тип определяется типом переменной или другого источника/приёмника откуда ты берёшь или
> куда ты кладёшь значение. Если ты используешь операцию + для сложения
> целых, то она сложит целые. Если ты используешь её для сложения
> float'ов, она сложит флоаты. При этом при необходимости типы аргументов будут
> приведены до соответствия друг-другу.С float-ами соглашусь - там это специализированные команды сопроцессора, по крайней мере опять-же для 86-ой архитектуры. А вот для целочисленных это не так - там (в tasm/masm, а, если не ошибаюсь, с недавнего времени и в gas), add складывает как 8-ми битные, так и 16-ти и 32-х битные целые значения, как знаковые так и беззнаковые, вроде как одной и той-же командой (понятно, что для процессора эти команды разные, но для программиста - нет), а, опять-же в каких-то архитектурах типа 86 даже может прибавлять к регистру содержимое памяти.
> Особенно эти сишные типы заметны на указателях:
> для асма нет разницы между целым значением, void* и char*. Ты
> когда пишешь на асме думаешь об указателях как о целых числах.
> В C же, указатель с некоторой натяжкой можно назвать целым числом,
> но в зависимости от типа указателя операция сложения будет выдавать разные
> значения. (char*)0 + 1 даст 1, а (int*)0 + 1 даст
> 4.С этим - согласен. Хотя его предок, B, если правильно помню вполне себе был безтиповым, т.е. у него, если правильно понимаю, был тип int и был, формально, указатель void*, правда как он там с переменными с плавающей запятой обходился не знаю, возможно для той архитектуры их просто не было.
> В C есть функции -- это тоже абстракции. В ассемблере есть код
> и есть данные, деление между ними условно -- ты можешь сделать
> jmp на данные, или прочитать байт кода в регистр. В асме
> ты можешь создавать функции, но при этом ты можешь сделать call
> в середину функции, или jmp из одной функции в другую. И,
> я отмечу, это не всегда глупость, это может быть вполне осмысленным
> и полезным действием. Скажем, tail call'ы так и делаются -- вместо
> call func/ret, мы делаем jmp func. Функции с несколькими точками входа
> тоже не редкость в асме.Должен-же он был чем-то отличаться от ассемблера, кроме синтаксиса. Да и заявлялось, что C - это язык высокого уровня, и до сравнительно недавнего времени так и было. Это теперь его уже считают языком среднего уровня - выше ассемблера, но ниже всех остальных.
> Абстракции есть в любой проблеме, о которой ты в состоянии думать. Если
> ты не видишь этих абстракций, значит ты недостаточно глубоко копнул.Если Вы сразу не поняли, то то сообщение был сарказм. Постараюсь в следующий раз как-то дополнительно помечать такого рода сообщения. Впрочем, всё-равно было интересно Вас почитать. Спасибо.
> С float-ами соглашусь - там это специализированные команды сопроцессора, по крайней мере
> опять-же для 86-ой архитектуры. А вот для целочисленных это не так
> - там (в tasm/masm, а, если не ошибаюсь, с недавнего времени
> и в gas), add складывает как 8-ми битные, так и 16-ти
> и 32-х битные целые значения, как знаковые так и беззнаковые, вроде
> как одной и той-же командой (понятно, что для процессора эти команды
> разные, но для программиста - нет), а, опять-же в каких-то архитектурах
> типа 86 даже может прибавлять к регистру содержимое памяти.А на других архитектурах? Где-то сопроцессор, где-то нет. А знаковые/беззнаковые умножения/деления? Тип операнда определяется кодом операции и всякими флагами в ней, а не свойствами операндов.
>> Абстракции есть в любой проблеме, о которой ты в состоянии думать. Если
>> ты не видишь этих абстракций, значит ты недостаточно глубоко копнул.
> Если Вы сразу не поняли, то то сообщение был сарказм. Постараюсь в
> следующий раз как-то дополнительно помечать такого рода сообщения.Да, это поможет.
> Впрочем, всё-равно было интересно Вас почитать. Спасибо.
Пожалуйста. Но в общем не за что.
> Опять-же
> для tasm-ов была возможность даже объявлять переменные на стеке в соответствии
> с определённой callcing convention, и тогда написав что-то типаОно, ЕМНИП, для всех более-менее популярных "человеческих" x86 ассемблеров было - MASM, TASM, NASM, FASM
Но "круче" в этом плане IMHO все же всякие "proto/proc/uses REG1, ... REGX" макросы - автоматом создавался стекфрейм, делался PUSH REG для register preservation (и что гораздо интереснее - перед каждым RET в этой "процедуры" – автоматически вставлялся POP REG1, ..., REGX), оформлялся вызов через INVOKE в нужном соглашении и даже, вроде бы, предупреждениями сыпало при несоответсвии кол. аргументов.Хотя и MASMовые "абстракции":
.IF al < FOO
print CurDir$()
...
mov hFile, fopen("testfile.txt") ; open the existing file again
mov flen, fsize(hFile) ; get its length
mov hMem, alloc(flen) ; allocate a buffer of that size
mov bwrt, fread(hFile,hMem,flen) ; read data from file into buffer
fclose hFile
...
.ELSE
или
.WHILE ecx < BAR*4
или
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
тоже "ничего так".
> Вырвиглазный синтаксис даже обсуждать лениво..Видимо для тех, кто не осилил?
а он вправду не очень по сравнение с джавой или шарпомне то чтобы откровенное говно, но меня на него ни разу не тянет
Он не очень даже по сравнению с С++
Уже переписали на Rust?
https://www.techempower.com/benchmarks/
И зачем нужна это скорость в синтетике бизнсу? Зачем эта скорость в синтетике пользователям? Спойлер: Пользы нет.
Есть польза
Например, тесты на моем компе:
NodeJs Fastify: 15к в секунду
C++ Pistache: 50-55
Go FastHttp: 70
Rust Actix: 80И если добавить больше логики, скриптовые языки просто потеряют скорости более чем в два раза, когда как компилируемые могут выжимать максимум из оптимизации, ресурсов сервера и ссд с бд (грубо говоря)
Без скриптовых языков выбор бэка вообще не особо велик, и Раст тут уже очень хороший вариант
Одна из причин, почему я начал его учить
Нет пользы. Увеличить скорость на 14% в синтетике и потратить в три раза больше времени на разработку чем на том же го. Время работы программиста дороже машинного времени. Поэтому вменяемый бизнес юзает джаву.
да, давай писать вся на сраном вебе, подумаешь там больше 50% производительности выкинуть и потребление озу раза в 4-5 поднять, зато время работы говнокодеров уменьшим! подумаешь, там перегревы устройств, или повышенное энергопотребление, постоянные лаги и подвисания, пипл схавает же. если ты ценишь время разработчика больше, чем оптимизацию, то ты один из тех кретинов, которые живут по принципу "хуяк хуяк и в продакшен", а чем вас больше, тем хуже все для технологий будет в будущем.
Так весь продакшн на этом принципе и держиться. Вспомнить хотя бы монстроузный COBOL или коммерческий софт 90-ых.
> да, давай писать вся на сраном вебе, подумаешь там больше 50% производительности
> выкинуть и потребление озу раза в 4-5 поднять, зато время работы
> говнокодеров уменьшим! подумаешь, там перегревы устройств, или повышенное энергопотребление,
> постоянные лаги и подвисания, пипл схавает же. если ты ценишь время
> разработчика больше, чем оптимизацию, то ты один из тех кретинов, которые
> живут по принципу "хуяк хуяк и в продакшен", а чем вас
> больше, тем хуже все для технологий будет в будущем.Именно так. По моим вот наблюдениям, большинство за оптимизациями не гонится. Мы оптимизируем только самые узкие места, от которых будут большие убытки. Основная задача -- это не сделать идеально. И даже не сделать так, "чтоб работало". Наиболее распространённая задача -- решить проблемы заказчика / юзера. А ему главное что? Чтобы у него хоть в каком-то виде было всё необходимое. Железо дёшево. Электричество тоже. Работает не идеально? Да и пофиг, если твоё приложение горизонтально масштабируется. Докупят ещё серверов и всё. Кретины пишут "хyяк хyяк и в продакшен"? Пфф, между прочим, уже давно. В начале нулевых этого уже было навалом. Да и в общем-то пусть. Поскольку таких большинство, есть опсы, задача которых -- минимизировать риски того, что этот кусок дeрьма упадёт на проде. А пользователю, который пользуется сервисом, плевать на то, что под капотом. Задача пользователя -- окупать затраты. И он окупает. Что ещё надо-то?
Через 15 лет таких как ты будут отлваливать роботы, чтобы отомстить за своих друзей, которые зависли и впали в кому из-за дерьмового кода. Скриньте.
Предварительная оптимизация - сущее зло. Пока тестировщик не пожаловался на скорость - пишите подджерживаемый код.Ну и желательно не пишите на JS и прочей xyетe с специалистами, которые по роликам на ютюбе учатся
Предварительная оптимизация == поддерживаемый код.
+ предварительная оптимизация это показатель компетентности и профессионализма (без неё можно просто передать проект более дешёвым индусам, послав хипстеров с завышенными хотелками на завод).Естественно, речь идёт не о тупом нагромождении моднявых абстракций, обмазанных лямбдами, а о грамотной оптимизации.
Увы, это не так. В двух последних компаниях где я работаю, таких сверхгениев на собеседовании просто вежливо отшивают.Поверьте мне
А пок тестировщики сидят на 64-ядерниках разогнаных под жидким азотом все остальные сосут лапу. Так и живем.
Я выбирал между Го и Растом фактически
Го не понравился, и синтаксис какой-то более всратенький
Так что будущее за РастомА Джава в 2020 - это садомазо.
> А Джава в 2020 - это садомазо.Почему? Как язык джава очень даже норм: типы статические, функцию в функцию положить можно. Юнит-тестирование божеское. IntelliJ есть. Обвязки для всего, что нужно есть. Андроид есть.
Я вообще не java-программист, но в 2020 году серьёзно бы рассматривал писать на java/kotlin
В Java куча своих приколов с синтаксисом, поэтому если надо JVM - то проще на котлине это написать. Или, если знаешь и умеешь - то на Scala.
Прости, пожалуйста, но на какой версии Java ты успел много покодить, чтобы почувствовать "приколы с синтаксисом"? А если ни на какой, то на чём основываются твои суждения?
Довелось слегка пописать под андроид, когда там была ещё 6 ява. Приколы с анонимными классами в случаях, когда нужна лямбда, быстро надоели и я срыгнул на иос - там хотя бы можно на сяшечке с плюсами поговнокодить. Да и лицензионные приколы с явой тоже не делают её оптимальным выбором. Сейчас ынтырпрайз на шарпе любит сидеть, или перелазит на скалу с котлином.
Ну, уже с выходом 8 Java всё стало заметно повеселее. Сейчас в 11 вообще достаточно приятно. Хотя мои коллеги-"дедушки" замечали, что надо немного переучиваться чтобы использовать улучшения уместно и эффективно. А от лицензионных проблем помогает openjdk. По поводу ынтырпрайза: он встречается практически на любом языке.
сам java простой язык, но одна из проблем в том, что java не компилируется напрямую в исполняемые файлы операционной системы, а та же hotspot jvm на C++ написана, так что есть сомнения...
AoT компилятор стабилизирован начиная с JDK 11, оно конечно еще не все умеет, но создается для этого.
> сам java простой язык, но одна из проблем в том, что java не компилируется напрямую в исполняемые файлы операционной системы, а та же hotspot jvm на C++ написана, так что есть сомнения...Опуская за скобки всякие лицензионные риски/батлы можно отметить новую "пилимую" Oracle фигню - GraalVM. Они там создают нечто большее, чем просто VM. На хабре вон есть перевод статьи прошлого года:
https://habr.com/ru/company/haulmont/blog/433432/
А именно про исполняемые файлы операционной системы, оттуда куски:
"
... Мы сказали, что Graal -это библиотека-компилятор и он может быть использован многими различными способами. Один из них — компиляция ahead-of-time в платформозависимый исполняемый образ, вместо компиляции just-in-time во время выполнения. Это похоже на то, как работает обычный компилятор, например gcc.<далее следует команда (с выводом в консоль) создания образа исполняемого файла с именем topten>
Эта команда создает платформозависимый исполняемый файл, который называется topten. Этот файл не запускает JVM, он не слинкован с JVM и он вообще никаким способом не включает в себя JVM. Команда native-image по-настоящему компилирует ваш Java код и Java библиотеки, которые вы используете, в полноценный машинный код. Для компонентов среды выполнения, таких как сборщик мусора, мы запускаем нашу собственную новую VM, которая называется SubstrateVM, которая, как и Graal, также написана на Java.
Если вы посмотрите на зависимости, которые использует topten, то увидите, что это только стандартные системные библиотеки. Мы можем перенести только один этот файл на систему, в которой даже никогда не была установлена JVM и запустить его там, чтобы проверить, что он не использует JVM или какие-либо другие файлы. Topten также достаточно маленький — исполняемый код занимает объем меньше 6 Мб.
...
"
И обращу внимание, пишется эта фигня на яве, а не на C++ (прям каким-то PyPy повеяло).
> Я выбирал между Го и Растом фактически
> Го не понравился, и синтаксис какой-то более всратенький
> Так что будущее за РастомЯ выбирал между экскаватором и подъёмным краном фактически
Экскаватор не понравился, и сиденье какое-то более всратненькое
Так что будущее за подъёмным краном
> в три раза больше временину и кто сказал, что на го писать быстрее?
> потратить в три раза больше времени на разработку чем на том же го.Откуда цифры? В смысле ты пробовал сам, и у тебя на расте получилось в три раза дольше, или ты на чей-то ещё опыт опираешься, или может на какое-то исследование?
> Поэтому вменяемый бизнес юзает джаву.
Не поэтому. В бизнесе и без программистов достаточно непредсказуемости, с которой как-то надо справляться. Ну, ты прикинь, занял ты где-то денег под проект, может квартиру заложил, пахал как папа-карло целый год, но проект не взлетел, и все деньги профукались. Весь в долгах как в шелках, квартиры нет, и... Да, можно застраховаться, можно запустить процедуру банкротства, и может быть не остаться на улице при этом. Но всё равно обидно. Для крупной компании это не столь критично, но если она заказала себе продукт и ждёт его через год, а через год ведущий программист приходит, и говорит что им надо ещё столько же денег и ещё один год, то... как в таких условиях можно вести бизнес?
Экономика предоставляет некоторые инструменты, типа кредитов, страховок и тп., для того, чтобы с неопределённостью жить, но это помогает лишь в ограниченной мере. Java предоставляет устоявшиеся технологии разработки софта, которые включают в себя и правила написания кода, и правила обучения новых программистов, которые следуя этим правилам выдают заранее предсказуемый результат, укладываясь в предсказуемые сроки. Предсказуемость процесса, снимает часть неопределённости, значит снижает риски. Может быть снижает доходы (если java жрёт больше ресурсов, то за них ведь платить придётся, то есть себестоимость выше), но снижение рисков по сравнению c rust'ом гораздо существеннее.
Васян на своём локалхосте может сидеть и сравнивать время разработки со скоростью работы программы. В некоторых проектах, где вычисления требуют тысяч ядер и видеокарт, а разработка программы требует не менее десяти лет работы команды из нескольких PhD разных специализаций и нескольких программистов, менагеры могут чесать репу, сравнивая время разработки со стоимостью железа для запуска результата разработки. Во вменяемом же бизнесе (то есть в большинстве случаев), стоимость разработки и железа маргинальна, важнее заранее и точно знать, что и когда будет создано.
В наших отечественных реалиях главный риск менеджмента разработки - это найти людей. Говнокодеров на Java худо бедно хватает. Хоть выбор какой-то есть на рынке.
Это наверное наиважнейшая часть той самой предсказуемости.
С++ разработчики - мало и выбрать не из чего.
JS - совсем задрали ценник.
Go - вроде модно, но народу немного и выбор как в советском магазине в провинции в 1990 году.
И окромя Java разработчиков брать никого не хочется.
>> C++ Pistache: 50-55
>> Go FastHttp: 70
>> Rust Actix: 80Rust хвалится zero cost abstractions, абстракции C++ и Go, выходит, сами тебе доплачивают?
Go - обычный язык со сборщиком мусора
А на C++ просто нет хороших и удобных веб-фреймворков
Для серьезных беков учи яву. Или будешь ждать 10 лет пока все поменяется?
> Для серьезных беков учи явуЧто за стереотипное мышление?
Или хочешь сказать, что "серьезный бек" написать больше ни на чём невозможно?
Джава отнюдь не панацея.
В моем понимании "серьезный" - предназначеный для зарабатывания денег. Ява тут только потому, что более предсказуема: по человеческим ресурсам, по экосистеме, по вычислительным ресурсам (предсказуемо жрёт дохера, но при этом относительно стабильно). Язык и виртуальная машина с технической точки зрения твердое 3 с плюсом по пятибальной, но эти технологии в своё время оказались в нужном месте, заняли свою нишу и вылетать оттуда будут долго и постепенно.
как насчет C#?
>Язык сфокусирован на безопасной работе с памятью, обеспечивает автоматическое управление памятьюЕсли долго использовать их браузер, то он начинает жрать много памяти, а после закрытия процесс будет долго висеть, после чего вылетит.
Раст не Гугл пишет, если что
Я знаю, если что. Их поделкой (чистым хромом) не пользуюсь, поэтому о его стабильности ничего не скажу.
Мозилла писали писали браузер. Не получается. Все дело в плохом языке программирования - решила Мозилла. Теперь они пишут пишут язык программирования. Все жду, когда они решат, что все дело в плохих операционных системах, а затем и в плохих архетектурах ПК.
так то уже есть:
* RISC-V
* Redox
> когда они решат, что все дело в плохих операционных системах, атак они уже - но что-то с мазилаОС не взлетело - наверное, из-за плохого языка программирования.
> затем и в плохих архетектурах ПК.
ой... не подсказывайте им.
> что-то с мазилаОС не взлетелоВзлетело, но уже без Мозилы и на бедном рынке:
> In market share study results announced in May 2018, KaiOS beat Apple's iOS for second place in India,[15]
Ну все можно теперь брать процессор RISC-V и.... все. Может это будет единственная ось что сможет что-то предложить на данном проце.
С браузером у них всё получилось. То что в психушке психов жрущих хромое больше чем врачей, вина не мозиллы, а закон природы.
Саммари секции комментов:
- Почему вы не любите раст?
- Сложна. Ну, и как водится, нинужна
Это здешние комментаторы такие крутые спецы потому что
Саммари секции комментов:
- Почему вы не любите брейнфак?
- Сложна. Ну, и как водится, нинужнаfixed
Тебе никто ничего не обязан доказывать.
Но, пока C++ становится всё сложнее и не фиксит сплошные UB и сегфолты, Раст просто мирно развивается, и с каждым релизом всё вкуснее для переезда на него.А что Мозилла? В Firefox уже довольно много кода на Расте. Или Лиса недостаточно продукшн?
Пока Раст мирно развивается, для C++ напишут еще пару миллионов полезных библиотек для всех областей IT от игр до распределенных вычислений
Которые ощутят все прелести unsafe программирования.
Пишу на C++ далеко не первый год, да и до этого косвенно взаимодействовали. И честно, надоело. Да, если писать аккуратно и современно, всё отлично. До первой случайной ошибки, которую не каждый анализатор найдет. А компилятор съест и ещё спасибо скажет.
Ко всему прочему, у каждой такой либы будет свой стиль программирования, кто-то вообще в C-style уйдет.Я уже молчу об отсутствии таких простых банальных вещей как общий репозиторий либ, когда релиз либы = добавление в репу. Да, попытки создать нечто есть, но они локальные и жалкие. Тогда как в других языках это просто _есть_.
Раст - эдакие плюсы, без тягот обратной совместимости, с репом либ, с компилятором от авторов языка, с вкусными сахарными решениями, которых никогда не будет в плюсах.Впрочем, у плюсов много проблем, которые можно исправить не ломая эту самую совместимость. К примеру, добавить на этап компиляции варнинги уровня проверок Раста. Создать единую репу либ, желательно с упором на использование модулей (ага, и ещё лет десять ждать, пока хотя бы актуальные либы перейдут на модули), много чего можно сделать, и плюсы заиграют новыми привлекательными красками. Но не делается. И это обидно. Но, осознавая это, руки всё больше тянутся к языкам, где это так или иначе есть.
Rust мирно развивается, C++ агрессивно извивается.
> C++ становится всё сложнее и не фиксит сплошные UB и сегфолтыНу становится сложнее он в основном благодарая добавлению фич для разработки без UB и сегфолтов. Я согласен, что чтобы в нём разобраться, надо изрядно упороться, но rust, сделанный по его образу и подобию, уже не сильно лучше (хотя исходная задумка была неплохой).
Не сильно лучше? Ну-ну. У меня в Rust проекте на 6000 строк за все время не было ни одного сегфолта и ни одной утечки памяти. При этом писать такой код намного легче, чем на C++. И Rust сделан совершенно не по образу и подобию C++. Извините, но вы несёте чушь. Фактически Rust - это современный ML без GC и с низкоуровневыми фичами. На C++ он похож только если сильно прищуриться и попрыгать.
Не так уж имного там кода на Расте, если честно. Он есть, конечно, но в основном вспомогательный.
webrender весь на расте
Ребят, много новых криптовалют делаю на Rust или C++. Посмотрите тему, интересно.
Там и на Go шлёпают, и даже на node.js есть блокчейны. Поди кто-то не от мира сего, ещё и на php пилит.
я на перле встречал!
Какие такие, жизненные ситуации могут сложится, чтобы человек начал понимать для чего реально нужна изменяемая и неизменяемая переменная?
Это легко - надо почитать доку на ownership.
Мне этого не хватило. Мне пришлось после доков месяца три ходить по граблям, воюя с компилятором и иногда запрашивая помощи у реддита, когда самостоятельно справиться с компилятором мне не удавалось. Мне стало легко лишь тогда, когда я, читая ошибки компилятора, начал понимать как нарушились бы инварианты языка, если компилятор молча проглотил код, вместо ругани.
Я знаю две такие жизненные ситуацию: rust и стажировка под присмотром крутого чувака, который знает как надо, внимательно читает весь твой код, и пинает в живот за кажый ошибочный выбор между mut и const. Rust мне кажется менее травматичен, потому что конфликты с компилятором менее травматичны (как психологически, так и физиологически), нежели конфликты с крутым чуваком.
командная разработка
Написание программ исходит из сочинительства.
Андрей Макаревич был бы отличным программистом.Вот море молодых. Айфоны их дороги.
Мне триста лет, я выполз из тьмы.
Они "торчат от GO".
Скриптами "пудрят мозги".
Они не такие как мы.
Я не горю желаньем лезть в чужой монастырь.
Я видел COM на C без прикрас.
Не стоит прогибаться под изменчивый мир.
Ну вот и всё!
Мы пишем на RUST.Теперь, всё мы пишем на RUST.
Один мой друг.
Он стоил двух.
И не букинист™.
Всегда везде "решётку" хвалил.
Работал он на Гейтса, как C# программист.
А тот взял да "свалил".
Ну, что же.
Спи спокойно. Ведь на C ты "забил".
И брал свои вершины не раз.
Не стоит прогибаться под изменчивый мир.
Ну вот и всё!
Мы пишем на RUST.Теперь, всё мы пишем на RUST.
Другой, держался русла.
И течение ловил.
Подальше от "плюсовых" кодов.
Он был как все.
И плыл как все.
И вот он приплыл.
Ни ядер. Ни клонов. Ни BoF.
И жизнь его нагнула в этот "JAVA-кефир".
Где KOTLIN не поможет за раз.
Не стоит прогибаться под изменчивый мир.
Ну вот и всё!
Мы пишем на RUST.Теперь, всё мы пишем на RUST.
Оппааааанькиииии..........
Пусть "лажа" возражает, и жена всё "пилит":
-"Ушёл бы ты давно в COPY-PAST!".
Не стоит прогибаться под изменчивый мир.
Ну вот и всё!
Мы пишем на RUST.Ну вот и всё!
Мы пишем на ⭐RUST⭐.Автор исходника: Андрей Макаревич
Группа: Машина времени
Песня: Однажды мир прогнётся под нас
Год: 1997
букинист™->любитель покупать книги по программированию.Если вышеизложенный комментарий - не удовлетворяет,
тогда можно Клонировать текст программы по другому.
Например в стиле 60-х годов:<...... Но снова качает, качает.
Задира-ветер фонари над головой.
И снова шагает, шагает.
Весёлый парень по весенней мостовой.Листает, листает, листает.
Учебник JAVA он листает на ходу.
Не знает, не знает, не знает.
Что каждым утром он читает "Лабуду".Пройдет много лет и поймет наш студент.
Что формулы счастья у JAVA уж - Нет.Есть в книжках твоих много истин таких.👾
А формула счастья Давно у Других!>🦀Автор исходника: Куклин Л. жив 86 лет
Композитор: Колкер А.
Исполняет: Мария Пахоменко.
Год: 1964