LINUX.ORG.RU

Rust 1.27

 


3

10

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

Основные изменения:

  • SIMD — наиболее значимое и ожидаемое нововведение: стабильная версия Rust обзавелась базовой поддержкой SIMD.
    Для примера использования рассмотрим следующий сниппет:
    pub fn foo(a: &[u8], b: &[u8], c: &mut [u8]) {
        for ((a, b), c) in a.iter().zip(b).zip(c) {
            *c = *a + *b;
        }
    }
    
    Здесь мы берем два слайса, складываем числа в них и помещаем результат в третий слайс. Самый простой способ, описанный выше — это проход в цикле по каждому слайсу, сложение и сохранение результата. Впрочем, это можно сделать быстрее и в LLVM может автовекторизовать такой код, подставив SIMD инструкции автоматически.

    Стабильный Rust уже давно использует возможности автовекторизации LLVM, но, к сожалению, компилятор может использовать подобные оптимизации не всегда. В Rust 1.27.0 добавлен модуль std::arch, включающий базовую поддержку использования инструкций SIMD напрямую из кода на Rust. Кроме того, добавлены соответствующие директивы условной компиляции:

    #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"),
          target_feature = "avx2"))]
    fn foo() {
        #[cfg(target_arch = "x86")]
        use std::arch::x86::_mm256_add_epi64;
        #[cfg(target_arch = "x86_64")]
        use std::arch::x86_64::_mm256_add_epi64;
    
        unsafe {
            _mm256_add_epi64(...);
        }
    }
    
    В примере выше флаги cfg позволяют выбрать правильную версию функции в зависимости от целевой архитектуры во время компиляции. Также мы можем это сделать в рантайме:
    fn foo() {
        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
        {
            if is_x86_feature_detected!("avx2") {
                return unsafe { foo_avx2() };
            }
        }
    
        foo_fallback();
    }
    

    Примитивы, включенные в стандартную библиотеку обеспечивают минимальную поддержку и весьма низкоуровневы, но их включение позволяет развивать более выкокоуровневые примитывы в библиотеках. К примеру, крейт faster предоставляет удобный интерфейс, основанный на концепции итераторов.

    Без SIMD

    let lots_of_3s = (&[-123.456f32; 128][..]).iter()
        .map(|v| {
            9.0 * v.abs().sqrt().sqrt().recip().ceil().sqrt() - 4.0 - 2.0
        })
        .collect::<Vec<f32>>();
    

    С SIMD (faster)

    let lots_of_3s = (&[-123.456f32; 128][..]).simd_iter()
        .simd_map(f32s(0.0), |v| {
            f32s(9.0) * v.abs().sqrt().rsqrt().ceil().sqrt() - f32s(4.0) - f32s(2.0)
        })
        .scalar_collect();
    

  • dyn Trait

    Изначальный синтаксис трейт-объектов в Rust — одна из тех вещей, о введении которых мы жалеем: для некоторого трейта Foo, его трейт-объект будет выглядеть так: Box<Foo>

    И если Foo является структурой, синтаксис аллокации структуры в «куче» будет выглядеть точно так же.

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

    То же самое справедливо для случая impl SomeTrait for SomeOtherTrait, что является корректным синтаксисом, но интуитивно понимается как реализация трейта SomeTrait для всех типов, реализующих SomeOtherTrait, но на самом деле это записывается как impl<T> SomeTrait for T where T: SomeOtherTrait, в то время как первый вариант является реализацией трейта для трейт-объекта.

    Кроме того, появление impl Trait в противовес Trait ввело некую неконсистентность при обучении языку.

    Исходя из этого, в Rust 1.27 мы стабилизируем новый синтаксис dyn Trait.
    Теперь трейт-объейты выглядят так:

    // old => new
    Box<Foo> => Box<dyn Foo>
    &Foo => &dyn Foo
    &mut Foo => &mut dyn Foo
    

    То же самое применимо к другим типам указателей:
    Arc<Foo> теперь объявляется как Arc<dyn Foo>.

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

  • #[must_use] для функций
    Наконец, атрибут #[must_use] получил новые возможности: теперь он применим к функциям.

    Раньше он использовался только на типах, таких как Result<T, E>, где возвращаемое значение должно быть использовано, но теперь возможно такое применение:

    #[must_use]
    fn double(x: i32) -> i32 {
        2 * x
    }
    
    fn main() {
        double(4); // warning: unused return value of `double` which must be used
    
        let _ = double(4); // (no warning)
    }
    

    Также этот атрибут был добавлен к некоторым функциям в стандартной библиотеке, таким как Clone::clone, Iterator::collect и ToOwned::to_owned, теперь компилятор предупредит в случае, если их результат останется неиспользованным, что поможет заметить и предотвратить случайный вызов затратных операций.

Стабилизация стандартной библиотеки

Новые возможности Cargo

В текущем релизе в Cargo включены два маленьких нововведения:

Во-первых, Cargo теперь принимает флаг --target-dir.

Во-вторых, Cargo теперь будет пытаться автоматически найти тесты, примеры и исполняемые файлы (прим. бинарные подпроекты в библиотечных крейтах) в проекте, но явная конфигурация всё же будет требоваться в некоторых случаях.

Для помощи в конфигурации мы добавили несколько ключевых слов в Cargo.toml.

Обновить Rust можно с помощью команды:

curl https://sh.rustup.rs -sSf | sh # если у вас еще не установлен rustup
rustup update stable

>>> Подробности

★★★★★

Проверено: tailgunner ()
Последнее исправление: cetjs2 (всего исправлений: 5)
Ответ на: комментарий от RazrFalcon

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

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

при этом, только недавно научился в абы какую асинхронность, а тебя сахар волнует

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

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

Делают. Веб-морд ко всяким плеерам и торрентокачалкам и бэкапилкам уйма. Просто бэкендщики обленились, привыкли, что у них инструментарий не обновляется десятилетиями. Бэкендщик пишет очередной mp3-плеер на джанге и постгре. Потом создает сайт, с гигантской инструкцией как запустить этот чудный плеер при помощи mod_python, systemd и pgadmin. Естественно, никому он нафиг не вперся. Юзеру надо скачать и запустить, а не мутировать в сисадмина

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

В плане скриптов гораздо лучше подходит баш

Ха-ха-ха, НЕТ.

Для простых скриптов тебе родина дала POSIX Shell. Как только появляется желание использовать фичу из баша - надо сразу выкинуть недоязычок и взять питон.

Ну и тех, кто не отличает sh от bash, вообще за людей считать не следует. Как увидишь bash-скрипт с #!/bin/sh - говноскрипт в мусорку, автора в биореактор. За #!/usr/bin/bash вместо #!/usr/bin/env bash - в первый раз предупреждение по голове, во второй раз - биореактор.

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

В плане скриптов гораздо лучше подходит баш

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

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

Ты про tasklets в Stackless? В Stackless, заметь, не в CPython (есть ещё greenlet, но ненужно, а с async/await в третьем и подавно). Для питона очень много сторонней годноты есть, и PyPy, и Cython, и ironPython, вот только толку с этого чуть. Пока CPython не станет нормальным, это круто, но не особо полезно, тем же PyPy никто не пользуется. И в Go не совсем гринлеты, он таки параллелится и на уровне системных потоков.

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

gevent

Он как раз на greenlet. И если уж вспоминать всё это непотребство, то начинать надо было с twisted.

Ты реально не видишь разницы между тучей абстракций и нативными механизмами языка?

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

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

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

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

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

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

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

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

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

В сях тоже чего только нет

В сях есть всё. Открой любимый пакетный менеджер: все пакеты, начинающиеся с lib* — это то, что есть в сях

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

какую такую задачу может решать мелкий скрипт, что там не справится баш?

Любая задача с ветвлением.

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

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

Он справится, но будет сосать всю дорогу

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

Ну а что он виляет. Как-будто внешние либы не считаются

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

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

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

Я к башу на пушечный выстрел не подхожу. Баш - это сишка из мира скриптов.

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

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

Да, я. И как использовал python, так и продолжаю.

сколько еще лет тебе нужно практиковаться

Зачем, если на питоне сразу всё работает?

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

Зачем, если на питоне сразу всё работает?

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

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

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

В deb-based, в федоре, в сьюзе, даже в опениндиане там лежит баш, точно знаю что его там нет во фряхе и в никсосе, а так, полагаю, что есть почти везде, а много где и /bin/sh будет туда симлинком.

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

Си++ с std::filesystem - вполне себе замена башу.

Так у вас цепепе вполне себе замена всему, я давно не удивляюсь.

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

Ваше мнение очень важно для нас. Оставайтесь на линии.

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

Гланул в твой профиль.

Ненужно:

* Autotools * Bash * C * CMake * GTK+ * Go * LaTeX * Tk/Tcl * wxWidgets

У тебя, оказывается, всё нужно ненужно. Хотя последние два и CMake реально нинужно.

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

Так у вас цепепе вполне себе замена всему, я давно не удивляюсь.

Ты всё перепутала.

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