LINUX.ORG.RU

Rust быстрее С++? Аргументы.

 ,


2

9

Немного поизучал Rust, и решил собрать все преимущества заявляемые адептами.

  1. Из-за знания компилятором, что & mut - это уникальная ссылка, то параметры функции не будут алиаситься с обычной ссылкой:
fn f(s: & mut str, s2: & str) -> type // s и s2 указывают на разную память, 100% компилятор знает об этом
// в стандарте С++ нет restrict
  1. Возможно, большие возможности в compile-time чем у С++, в частности упоминается возможность прочитать файл во время компиляции:
const IMAGE: &[u8] = include_bytes!("/path/some_file.png");
  1. Map в rust реализован с помощью алгоритма BTreeMap, а в С++ - std::map красно-чёрное дерево, BTreeMap быстрее…

  2. HashMap в rust - открытая адресация, в С++ std::unordered_map - метод цепочек, открытая адресация быстрее…

  3. В rust нет объектов, везде используется memcpy, а тот же resize вектора делается через realloc, бысрее чем move конструкторы в С++

помогите дополнить список.

возможно, в будущем прочтём в блоге у царя, где он помножит на ноль все эти преимущества.

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

и я верну

на 90% состоит из unsafe

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

Вот пример, который помог мне понять:

Vec обычная структура стандартной библиотеки, где есть указатель на данные, capacity и len и есть такая функция:

imp <T> Vec<T> {
    pub unsafe fn set_len(& mut self, new_len : usize) {
        self.len = new_len;
    }
}

В ней не вызываются C функции или ещё какая-нибудь магия, а просто меняется значение внутренней переменной len, но эта функция обязана быть unsafe, так как могут нарушиться инварианты вектора.

А многие раст программисты просто стараются спрятать unsafe за safe, как например тут: Бенчмарки parallel-rust против c++ (комментарий) и не думают об инвариантах кода.

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

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

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

Это понятно, split_at_mut лучший пример идеально safe кода, в котором оправдано unsafe внутри, так как в самом интерфейсе строго следят за инвариантами

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

Ну пока не сделали. Примеры relm выглядят так себе. И я не увидел как динамически создавать виджеты.

QML в разы проще.

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

Нет, b tree быстрее только при очень дорогом доступе к памяти

А щас он типа дешёвый?

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

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

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

И при чём тут раст?

Ну, видимо, поколение Z будет писать гуй в виде спец синтаксиса, преаращающегося в композицию функций. Flutter, Swift UI, JSX тут причем. А раст пока не причем, да

Так можно и питон ругать

Петон можно по всякому ругать

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

А разве Шекспир не англосакс? Емнип, он из самой что ни на есть английской Англии был.

По-твоему, в Англии только англо-саксы были?

seiken ★★★★★
()

Да просто быстрее, без аргументов.

И длиннее, и толще.

Пишите себе на здоровье.

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

Когда вы извлекли пользу из borrow checker,

Из чего ещё там можно извлечь пользу?

LamerOk ★★★★★
()
Ответ на: Не в тему от WitcherGeralt

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

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

схемки, которая js без синтаксиса

А в js уже завезли call/cc? Там же вроде даже оптимизации хвостовой оптимизации нет.

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

call/cc

Генераторы чтоли? Сто лет как уже есть

хвостовой оптимизации

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

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

Генераторы чтоли? Сто лет как уже есть

Сохранение продолжений, например, чтобы из map вернуть текущую точку обхода, сохранить её, а потом продолжить обход коллекции (возможно несколько раз).

Генератор — это всего лишь замыкание.

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

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

Рекурсия не только для списков годится.

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

например, чтобы из map вернуть текущую точку обхода, сохранить её, а потом продолжить обход коллекции

const map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

// Возвращаем текущую "точку обхода"
const mapIter = map.entries();

// Продолжаем "обход коллекции"
console.log(mapIter.next().value);
console.log(mapIter.next().value);

Генератор — это всего лишь замыкание.

WAT

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

Не вижу причин любить язык ради рекурсии) Я сравнивал с js по типизации. Вот это описание латентности крайне огорчает:

Nevertheless, the point is that there is nothing in Scheme which requires the procedure parameters always to be strings, or x always to hold a numeric value, and there is no way of declaring in your program that such constraints should always be obeyed. In the same vein, there is no way to declare the expected type of a procedure’s return value.

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

// Возвращаем текущую «точку обхода»

Это итератор, который приходится делать отдельно в Map.

А я про ситуацию, когда у тебя

a = new Array...
b = a.map(f)

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

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

В scheme можно записать состояние, спросить пользователя, и вернуться к продолжению обработки массива

А. прикольно

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

WAT

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

Полностью эквивалентно

(define (generateSequence)
  (define (next) 
    (set! next next2)
    1)
  (define (next2)
    (set! next next3)
    2)
  (define (next3)
    3)
  (lambda () (next)))
monk ★★★★★
()
Ответ на: комментарий от Deleted

Ага. А ещё крайне удобно сайты писать. Когда кусок кода, который формирует страницу, может сформировать, например, страничку для запроса логина/пароля или ещё чего-нибудь, и в зависимости от того, что пользователь введёт, продолжить формирование страницы.

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

Nevertheless, the point is that there is nothing in Scheme which requires the procedure parameters always to be strings, or x always to hold a numeric value, and there is no way of declaring in your program that such constraints should always be obeyed. In the same vein, there is no way to declare the expected type of a procedure’s return value.

В Racket можно. Есть контракты в которых можно указывать почти что угодно (например, что результатом функции sort должен быть отсортированный массив, с теми же значениями, что и аргумент, или что результатом должна быть функция, возвращающая числа не меньше указанного аргумента). И есть Typed Racket, в котором типы проверяются при компиляции.

(: sum-list (-> (Listof Number) Number))
(define (sum-list l)
  (cond [(null? l) 0]
        [else (+ (car l) (sum-list (cdr l)))]))

Включая параметрические функции:

(: fold-left
   (All (C A B ...)
        (-> (-> C A B ... B C) C (Listof A) (Listof B) ... B
            C)))
(define (fold-left f i as . bss)
  (if (or (null? as)
          (ormap null? bss))
      i
      (apply fold-left
             f
             (apply f i (car as) (map car bss))
             (cdr as)
             (map cdr bss))))
monk ★★★★★
()
Ответ на: комментарий от Deleted
#lang web-server/insta
(require web-server/formlets web-server/page)

(define login-formlet
  (formlet
   (div (div (label "Имя")
             ,{input-string . => . login})
        (div (label "Пароль")
             ,{(to-string (required (password-input))) . => . password}))
   (list login password)))

(define cont #f)

(define/page (start)
  (let/ec return
    (response/xexpr
     `(html (body
             ,(if (equal? (let/cc k (set! cont k) (return (login (current-request)))) '("login" "pass"))
                  "ok"
                  "failed"))))))

(define/page (login)
  (response/xexpr
   `(html (body (form ([action ,(embed/url accept-login)]) ,@(formlet-display login-formlet) (input ([type "submit"])))))))

(define (accept-login request)
  (cont (formlet-process login-formlet request)))

Запускать из DrRacket. Если нужно из консоли, то в конце добавить (serve/servlet start) и заменить #lang web-server/insta на

#lang racket
(require web-server/servlet web-server/servlet-env)
monk ★★★★★
()
Ответ на: комментарий от Deleted

Могу пошагово описать, что там происходит

login-formlet – просто описание полей формы для ввода, (formlet-display login-formlet) выдаст ‘<label «Имя»>….’, а (formlet-display login-formlet request) вытащит из полей формы значения и вернёт (list login password).

(embed/url accept-login) внутри define/page возвращает ссылку при переходе по которой вызовется функция accept-login (чтобы в неё попали результаты формы из браузера).

(let/ec return …) позволяет внутри взывать (return xxx) чтобы выйти из блока и вернуть xxx. Как в JS оператор return.

(let/cc k (set! cont k) (return (login (current-request)))) делает всю магию с продолжениями. (let/cc k (set! cont k) …) сохраняет продолжение в переменной cont. Затем (return (login (current-request))) возвращает из start результат функции login. Пользователь видит форму для ввода логина и пароля.

В cont сохранилось продолжение. Теперь если вызвать (cont xxx), то вызовется функция start, в которой вместо (let/cc k …) подставлено значение xxx.

В accept-login мы получаем список из логина и пароля через (formlet-process login-formlet request) и через cont передаём его в продолжение start. Поэтому вызов accept-login закончится выполнением (вместо xxx список из логина и пароля)

(response/xexpr
   `(html (body
           ,(if (equal? xxx '("login" "pass"))
                "ok"
                "failed"))

Соответственно, в зависимости от значения xxx будет отрисован один из вариантов страницы.

В принципе, можно было всё это оформить как

(define/page (start)
  (let/ec return
    (define login-pass (let/cc k (set! cont k) (return (login (current-request))))    
    (response/xexpr
     `(html (body
             ,(if (equal? login-pass '("login" "pass"))
                  "ok"
                  "failed"))))))

Может так понятней. К слову, таких выходов-возвратов может быть много. Типа

(define-syntax-rule (get-from-user f)
  (let/cc k (set! cont k) (return (f (current-request)))))
(define login-pass (get-from-user login-page))
(define age (get-from-user age-page))
(define category (get-from-user select-category-page))
(response/xexpr
     `(html (body ...
monk ★★★★★
()
Ответ на: комментарий от Deleted

Не вижу причин любить язык ради рекурсии)

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

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

Или норманом, или ещё хрен знает кем.

Какие норманы к 17-му веку в Англии?
Все пришлые уже давно были ассимилированы.
Ты ещё родившихся в 170м веке в Новгороде или там Старой Руссе обзови вараягами, ага.

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

Какие норманы к 17-му веку в Англии?

а какие англо-саксы? Это германские племена так же понаехавшие в британию, как все остальные.

seiken ★★★★★
()

Машинный код быстрее ассемблера. Обсуждаем.

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

Ну какбе англо-саксонские племена вытеснили бритов и со временем превратились в англичан.
А норманское нашествие представляло в основном смену феодала и права.
Если ты не понимаешь разницу между двумя этими событиями, то тут остаётся только развести руками и закончить с тобой разговор.

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

Влияние норманов на культуру значительное. А в 17м веке уже не было никаких нортумбрий, а была Англия.

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

Причём тут влияние, если мы говорим про конкретное происхождение, конкретного человека.
Если судить по генетической карте, то в родном городе Шекспира и окрестностях достаточно однородное население и да, они все потомки тех самых племён англо-саксов. То что их нынче называют англичанами, ну такое.
Что по поводу культуры, влияние нормандцы конечно оказывали, но не было никакого вытеснения и замещения.
Так что англичане достаточно однородны как в генетическом, так и культурном плане. Особенно что касается 17-го века.

Так что вероятность того что Шекспир был потомком кого-то ещё кроме англо-саксов стремится к нулю.

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

И теперь компилятор всунет UB

А потом догонит и ещё насуёт. Компиляторы они такие. Их хлебом не корми, только дай UB всунуть.

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