Обновить
64K+

Rust *

Мультипарадигмальный компилируемый язык

116,08
Рейтинг
Сначала показывать
Порог рейтинга

Инвертирование порядка сортировки в Rust

Rust позволяет легко сортировать элементы по ключу с помощью .sort_by_key, в примере ниже важные заметки будут помещены в конец:

struct Note {
    imp: bool,
    title: &'static str,
}
let mut notes = vec![
    // ...
];
notes.sort_by_key(|k| k.imp);

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

use std::cmp::Reverse;
// ...
notes.sort_by_key(|k| Reverse(k.imp));

Как это реализовано? Давайте взглянем на исходный код стандартной библиотеки Rust:

pub struct Reverse<T>(pub T);

impl<T: Ord> Ord for Reverse<T> {
    fn cmp(&self, other: &Reverse<T>) -> Ordering {
        other.0.cmp(&self.0)
    }
}

Все просто - это тип обертка (newtype) для исходного типа, и для типов с трейтом Ord она переопределяет Ord, но вместо сравнения self с other она сравнивает other с self, что означает - порядок в результате меняется на обратный. Просто и красиво!

Теги:
Рейтинг0
Комментарии5

❓100 Вопросов по Машинному обучению (Machine Learning) - Вопрос_9

?Вопрос_9: В чем разница между Rapids, Vaex, Pandas, Polars, Modin, Dask они же все для анализа данных ?

✔️Ответ:

  1. Pandas предоставляет гибкие структуры данных, такие как DataFrame, и мощные инструменты для манипуляции, фильтрации, агрегации и анализа данных. Pandas обычно используется для работы с небольшими и средними объемами данных, которые могут поместиться в оперативную память одного компьютера;

  2. Dask позволяет обрабатывать данные, превышающие объем доступной оперативной памяти, с использованием распределенных вычислений. Dask предоставляет абстракции, такие как DataFrame и Array, которые подобны структурам данных из Pandas и NumPyx;

  3. Polars обладает высокой производительностью благодаря использованию Rust в своей реализации, а также предлагает возможности параллельной обработки данных. Она может работать с большими объемами данных и поддерживает некоторые распределенные вычисления;

  4. Vaex использует ленивые вычисления и эффективные алгоритмы для выполнения операций над данными. Она обладает высокой производительностью и может работать с многопоточностью, многопроцессорностью и распределенными вычислениями;

  5. Modin предоставляет интерфейс, совместимый с Pandas, но с оптимизированной производительностью. Она использует различные движки обратной совместимости, такие как Dask и Ray, для распределенных и параллельных вычислений.

    https://t.me/DenoiseLAB

Теги:
Всего голосов 4: ↑4 и ↓0+4
Комментарии0

Разработчики языка программирования Rust предупредили об отключении 20 ноября 2023 года поддержки в репозитории crates.io неканонических загрузок, в которых используются нормализованные имена пакетов с заменёнными символами подчёркивания и дефиса. В качестве причины внесения изменения называется желание повысить надёжность и оптимизировать производительность.

До сих пор было неважно, подчёркивание или дефис указаны в имени при загрузке — crates.io автоматически приводил подобные ссылки к необходимому виду. Например, для размещённого в репозитории пакета «имя_пакета» при загрузке можно было указывать «имя‑пакета» и наоборот. В репозитории также присутствует защита от размещения похожих имён, не позволяющая разместить пакет с именем «имя‑пакета» если уже имеется пакет «имя_пакета».

Наличие процедуры нормализации имён требует вызова специального обработчика, что не позволяет напрямую использовать сети доставки контента для отдачи запросов на загрузку пакетов. Кроме того, перебор вариантов создаёт дополнительную нагрузку на бэкенды и БД проекта. Анализ логов показал, что неканонические имена используются только в запросах с User Agent cargo-binstall/1.1.2, Faraday v0.17.6, Go-http-client/2.0, GNU Guile и python-requests/2.31.0. Автор утилиты cargo-binstall, используемой для установки бинарных артефактов к пакетам, уже внёс изменения, учитывающие грядущее отключение поддержки неканонических имён.

Источник: OpenNET.

Теги:
Рейтинг0
Комментарии0

Компактный match в Rust

match часто используется для работы с енумами, посмотрим на такой пример:

enum NextStep {
    TurnLeft,
    TurnRight
}

fn main() {
    let next_step = NextStep::TurnLeft;
    match next_step {
        NextStep::TurnLeft => println!("turn left"),
        NextStep::TurnRight => println!("turn right"),
    }
}

Это может быть не очевидно, но енумы в Rust можно принести в текущее пространство имен, это позволяет сделать код более компактным:

// ...
    use NextStep::*;
    match next_step {
        TurnLeft => println!("turn left"),
        TurnRight => println!("turn right"),
    }
// ...

Ну, а чтобы ограничить эффект только одним match, придется задать границы используя {} для дополнительного блока:

// ...
    {
        use NextStep::*;
        match next_step {
            // ...
        }
    }
// ...
Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии3

Полезный антипаттерн в Rust

В Rust нередко используются типы обертки (newtype), которые помогают строже контролировать обрабатываемые данные.

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

struct Admins(Vec<u128>);

Теперь можно использовать этот тип:

fn print_admin_count(users: Admins) {
    println!("admins count: {}", users.0.len());
}

Это работает, но выглядит уже не так приятно, как если бы мы просто использовали массив users.len().

В Rust существуют типажи (traits) Deref/DerefMut, которые решают эту проблему, если мы реализуем их для типа обертки, то это позволит работать с внутренним типом напрямую:

impl Deref for Admins{
    //...
}

fn print_admin_count(users: Admins) {
    println!("admins count: {}", users.len());
}

Полный сниппет

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

Всего голосов 1: ↑1 и ↓0+1
Комментарии0

в Rust есть метод transpose, иногда бывает полезен, особенно хорошо работает с anyhow:

use std::str::FromStr;
use anyhow::Context;

fn add(a: Option<&str>, b: Option<&str>) -> anyhow::Result<f32> {
    let a = a.map(f32::from_str).transpose()?.context("not a value")?;
    let b = b.map(f32::from_str).transpose()?.context("not a value")?;
    Ok(a + b)
}

fn main() {
    println!("{:?}", add(Some("12"), Some("1.2")));
    println!("{:?}", add(Some("a"), Some("1.2")));
    println!("{:?}", add(None, Some("1.2")));
}

вывод:

Ok(13.2)
Err(invalid float literal)
Err(not a value)
Всего голосов 2: ↑2 и ↓0+2
Комментарии0