• Какие характиеристики у оперативной памяти при загрузке ее данными?

    @rPman
    Потребление энергии у DDR памяти не зависит от того, заполнена она или нет (там нет и не может быть флага - заполнена ячейка полезными данными или она свободна).

    Вся память обновляется в цикле целиком, т.е. это постоянный процесс, как минимальное потребление (оно действительно небольшое, хватает чтобы не съедать батарею в режиме сна)

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

    p.s. безотносительно выбора ОС, могу предположить что забитая оперативная память может повлиять на количество операций чтения с постоянной памяти (hdd или ssd) при условии что эти данные могут быть закешированы и кеш этот использован (т.е. данные читаются повторно). Вся свободная оперативная память ОС будет использована как дисковый кеш (в linux это настраивается но нет никакого смысла это менять), соответственно если эту память занять подо что то другое, данные будут чаще считываться с диска.

    Но потребление ssd/hdd при чтении данных, по сравнению с 'ничегонеделанием' очень мизерное. Боюсь что это так же не имеет особой значимости.
    Ответ написан
    5 комментариев
  • Как в rust конвертировать place expression в value expressions?

    vabka
    @vabka
    Токсичный шарпист
    Попробуй так
    fn main() {
        let funcs = {
            // Можно использовать не FnOnce, а что-то другое. Например Fn или FnMut. Но в любом случае придётся использовать dyn, тк наша лямбда берёт что-то из окружающего контекста.
    
            let mut funcs: Vec<Box<dyn FnOnce() -> usize>> = Vec::with_capacity(3);
    
            for i in 0..3 {
                let i_copy = i.clone(); // вообще clone() тут не нужен, тк usize реализует трейт Copy. Оставлено для примера
                funcs.push(Box::new(move || i_copy));
            }
            funcs
        };
        
        for func in funcs {
            let result = func();
            println!("{result}");
        }
    }

    https://play.rust-lang.org/?version=stable&mode=de...

    Другой вариант - делать не массив лямбд, а сделать структуру с методом и сделать массив структур.
    В твоём случае это будет эффективнее:
    #[derive(Copy, Clone, Debug)]
    struct Something(usize);
    impl Something {
      fn value(&self) -> usize {
        self.0
      }
    }
    
    fn main() {
        let items = {
            let mut items = Vec::with_capacity(3);
    
            for i in 0..3 {
                items.push(Something(i));
            }
            items
        };
        
        for item in items {
            let result = item.value();
            println!("{result}");
        }
    }

    https://play.rust-lang.org/?version=stable&mode=de...
    Ответ написан
    Комментировать
  • Вернуть владение значения типа структуры из функции на самом деле не возвращение владения, а поинтера на heap?

    vabka
    @vabka
    Токсичный шарпист
    Нет, эти два примера кода будут делать абсолютно разные вещи.
    В первом случае ты возвращаешь String, который содержит в себе несколько полей: len, capacity, и указатель на буфер.
    Во втором случае ты String ещё в кучу копируешь и возвращаешь указатель на String в куче.

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

    Ведь нет какой-то волшебной операции вернуть владение

    Она не волшебная, и она существует. Только владение не возвращается, а передаётся.
    Но существует только на уровне типов.

    https://play.rust-lang.org/?version=stable&mode=re...

    Первая функция:
    pushq	%rbx
    	movq	%rdi, %rbx
    	movq	__rust_no_alloc_shim_is_unstable@GOTPCREL(%rip), %rax
    	movzbl	(%rax), %eax
    	movl	$5, %edi
    	movl	$1, %esi
    	callq	*__rust_alloc@GOTPCREL(%rip)
    	testq	%rax, %rax
    	je	.LBB10_1
    	movb	$114, 4(%rax)
    	movl	$1701736041, (%rax)
    	movq	%rax, (%rbx)
    	movq	$5, 8(%rbx)
    	movq	$5, 16(%rbx)
    	popq	%rbx
    	retq

    Вторая:
    pushq	%r14
    	pushq	%rbx
    	pushq	%rax
    	movq	__rust_no_alloc_shim_is_unstable@GOTPCREL(%rip), %r14
    	movzbl	(%r14), %eax
    	movl	$5, %edi
    	movl	$1, %esi
    	callq	*__rust_alloc@GOTPCREL(%rip)
    	testq	%rax, %rax
    	je	.LBB11_6
    	movq	%rax, %rbx
    	movb	$114, 4(%rax)
    	movl	$1701736041, (%rax)
    	movzbl	(%r14), %eax
    	movl	$24, %edi
    	movl	$8, %esi
    	callq	*__rust_alloc@GOTPCREL(%rip)
    	testq	%rax, %rax
    	je	.LBB11_2
    	movq	%rbx, (%rax)
    	movq	$5, 8(%rax)
    	movq	$5, 16(%rax)
    	addq	$8, %rsp
    	popq	%rbx
    	popq	%r14
    	retq
    Ответ написан
    6 комментариев
  • Что то странно работает макрос в rust. Кому обращаться?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Ошибку вызывает то, что вы смотрите ютуб и спрашиваете ChatGPT. Прочитайте лучше учебник для начала, а потом можно будет и до документации по макросам добраться.
    Ответ написан
    Комментировать
  • Как объявить тип, который является коллекцией значений разных типов, которые можно конвертировать в другие типы ❌️с помощью trait-а Into❌️?

    vabka
    @vabka
    Токсичный шарпист
    В твоём случае тебе нужно завести новый trait, который будет брать ссылку на оригинальный объект, в отличие от Into. Потом ты сможешь сделать blanket implementation наподобие
    impl<T: Clone + Into<JsValue>> MyIntoJsValue for T {
        fn into_jsvalue(&self) -> JsValue{
            self.clone().into()   
        }
    }
    Ответ написан
    4 комментария
  • Откуда взялась ассоциативная функция from?

    vabka
    @vabka
    Токсичный шарпист
    В wasm-bindgen::JsValue Нету impl From for JsValue

    Всё там есть https://docs.rs/virtual-dom-rs/latest/virtual_dom_...
    impl From<Element> for JsValue
    + есть целый ряд blanket impl

    Не работает. Работает только с &element

    Потому что ты реализовал трейт для &element, а не для element.
    Сам же в начале написал, что
    Тут тоже подвоха нет. get_element_by_id() возвращает Option<Element>, а не Option<&Element>

    Вот такое уже работает:
    https://play.rust-lang.org/?version=stable&mode=de...

    Но эти поганые макросы наносят уроны документации, и не видно какие именно есть поля и функции у JsValue.

    Макросы на это влиять не должны. VS Code с rust-analyzer и intellij rust умеют показывать все impl для структуры, в том числе blanket impl и те impl которые возникли в результате вызова макроса.
    Ответ написан
    1 комментарий
  • Может ли Раст полноценно заменить Джаву в сфере финансовых технологий?

    mayton2019
    @mayton2019 Куратор тега Java
    Bigdata Engineer
    Докину 5 коп.

    Я думаю что никто такую задачу вобщем-то не ставит. И никогда не поставит. Тут не то что Java
    а я прошу прощения Cobol не могут никак заменить. Языку - уде более 50 лет возраста.
    И хотя проблема касается в основном США, но это просто пример того что код живет очень долго.
    У джунов уже седые бороды отрасли :)

    Язык Rust вобщем-то создавалася как язых обще-системного программирования с правильным
    механизмом управления памятью. И уже если ему и где-то конкурировать - так это там где нужен
    отклик (игры или реал-тайм приложения).

    Сильные стороны Java сегодня - это большой репозитарий библиотек на все случаи жизни.
    Статистика по maven https://mvnrepository.com/ заявляет что 35 миллионов артифактов
    имеется в наличии. Можно наверное найти любой драйвер или парсер или любую
    либу поддержки сетевых протоколов. Большая часть из них проверена временем.
    Production ready. Можно ли говорить о production-ready для Rust - библиотек я не знаю.
    Пускай знающие отпишут.

    Java - машина с развитым рантаймом. Рефлексия позволяет делать позднее инстанциирование
    компонентов через конфиги. И этим очень сильно пользуются во фреймворках. Фактически
    если проводить сравнительные анализы Rust и Java - мы встанем перед дилеммой - чем заменить
    механику рефлексии в Rust? Создавать рантайм? Но это противоречит идеям системного программирования
    или все таки принять как факт что Spring и ему подобные фреймворки принципиально нельзя
    воспроизвести в языке статической компилляции таком как Rust.

    Если-бы я сравнивал этот язык (Rust) - то ставил бы ему в одну весовую категорию Nim, Zig и прочие
    языки "пост-плюсового" периода. И в качестве задач я-бы ставил - разработку игр и драйверов
    для операционок. Вот там и тестируйте.

    Самому финтеху не всегда нужен рилтайм. Иногда - даже вообще не нужен. В батч-джобах биг-даты
    и python нормально работает. Специфика своя там. А критичные части бигдаты (Apache Arrow, Databricks Photon)
    - и так переписаны на сях чтобы быстринько search + join работал. В стриминге биг-даты - тоже вобщем-то
    CPU не сильно критичен. Там и Node и C# тоже годится в качестве языков. Вобщем задачи - I/O bounded.
    Ответ написан
    1 комментарий
  • Как разделить Cargo.toml на несколько файлов?

    vabka
    @vabka
    Токсичный шарпист
    Разделить Cargo.toml на несколько файлов нельзя.
    Разделять features на несколько штук я тоже не рекомендую - читать это будет сложно с учётом того, сколько фич в web-sys и как ты скорее всего будешь их добавлять

    В самом web-sys это автогенеренный код, но всё же:
    https://github.com/rustwasm/wasm-bindgen/blob/main...
    Ответ написан
  • Как в rust конвертировать place expression в value expressions?

    bingo347
    @bingo347
    Crazy on performance...
    Проблема с типами тут.
    Тип fn() -> u8 - это указатель на функцию. В него можно записать или обычную функцию с подходящей сигнатурой или замыкание, которое ничего не замыкает:
    fn some_func() -> u8 {
        0
    }
    
    let f: fn() -> u8 = some_func;
    let f: fn() -> u8 = || 0;

    Если же замыкание что-то замыкает (захватывает переменные из окружения), то это уже анонимная структура, хранящая в себе все захваченные значения (или ссылки на них), и у этой структуры просто перегружен оператор круглые скобки через трейты Fn/FnMut/FnOnce. Притом, так как компилятор генерирует для каждого замыкания в коде свою анонимную структуру, у каждого замыкания будет свой уникальный тип.

    Если массив замыканий полностью формируется в цикле, то замыкания будут одного типа и все скомпилируется:
    fn main() {
        let mut funcs = Vec::with_capacity(3);
        for i in 1u8..=3 {
            funcs.push(move || i);
        }
        
        for i in 0..3 {
            println!("{}", funcs[i]());
        }
    }


    P.S. для рэнжей есть литералы, не нужно их создавать через std::ops::RangeInclusive::<u8>::new
    Ответ написан
    2 комментария
  • Почему типы из заголовка cstdint доступны без его включения?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам повезло. Какой-то из включаемых вами других хедеров уже включает cstdint. Поскольку система инклудов в C++ идет еще из C и это дикое и неудобное легаси (текст хедера тупо вставляется в файл вместо include препроцессором), то такое рекурсивное включение работает.

    Но это плохая практика - стоит включать все, что вы используете всегда. Потому что потом вы что-то поменяете, исключив какой-то уже не нужный вам хедер отсюда, или из другого хедера, и у вас вылезет ошибка о неопределенных типах из cstdint.
    Ответ написан
    Комментировать
  • Что значит ссылка без типа?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    const &y = x;
    Это не ссылка без типа, а синтаксически неверный код, который не пройдет трансляцию за пределами GCC.

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

    В C++ нет типа по умолчанию, в отличие от С, где типом по умолчанию является int. Если в C код const y = x является синтаксически верным и подразумевает const int y = x, то в C++ этот же код является уже синтаксически неверным и не пройдет трансляцию.
    GCC в твоем коде отходит от стандарта C++ в пользу поведения как в C.
    Ответ написан
    2 комментария
  • Как использовать namespace в header?

    @res2001
    Developer, ex-admin
    Заверните весь код в input.cpp в namespace input {}
    namespace добавляет к символам в объектом файле имя namespace, но т.к. у вас определения в input.cpp не включены в namespace, то в объектном файле эти символа будут без добавления имени namespace, поэтому и undefined reference.
    Ответ написан
    Комментировать
  • Как включить предупреждение о небезопасном неявном касте?

    gbg
    @gbg Куратор тега C++
    Любые ответы на любые вопросы
    0) Такие ошибки возникают в рантайме, то есть тогда, когда приложение работает.
    1) Когда приложение работает, компилятор уже не участвует.
    2) Все эти ошибки C++ обрабатывает, только это надо запрограммировать
    Ответ написан
    Комментировать
  • Справа налево или слева направо представляются данные в виде битов в ячейках?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Правильный ответ - ни так и не эдак. Никак. Сравнивать указатели не из одного и того же массива - undefined behavior. Это было недавно в статье на хабре. Там ссылаются на раздел 3.3.8, "Relational operators".

    Более того, у вас там в программе еще UB: нельзя обращаться к данным в переменной long через указатель short - Это нарушение strict aliasing.

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

    На практике - никаких лево и право там не существует, есть только младшие и старшие адреса, читайте про big/little endian порядки байт. Они там бывают и так и эдак в разных архитектурах. В x86, например, младший байт имеет меньший адрес.
    Ответ написан
    Комментировать
  • Почему arr и &arr отображаются одинаково?

    @galaxy
    Массивы и указатели в C все же не совсем одно и то же. Пожалуй, просто дам ссылку на SO (там даже выдержка из стандарта приведена).

    Грубо говоря, переменные типа "массив" не всегда ведут себя идентично переменным типа "указатель на первый элемент массива". В частности, во всем известной конструкции:
    int arr[32] = {...};
    size_t N = sizeof(arr) / sizeof(arr[0]);

    И в ваш случай с оператором & тоже исключение.
    Ответ написан
    Комментировать
  • Static члены не копируют своих данных даже в наследниках?

    Vamp
    @Vamp
    Static члены не наследуются, верно. Так как это бессмысленно.

    Просто я думал, зачем же нужен в enum valueOf(). Разобрался. Предположил, что метод хранит в себе строковое представление констант, а затем сравнивает вводные данные с ними.

    Метод valueOf() ничего не хранит и компилятор подставляет одинаковую реализацию valueOf() во всех enum'ах:

    public enum Hello {
        FIZZ, BUZZ;
    
        // Данный метод автоматически генерируется компилятором.
        // Для любого enum'а.
        public static Hello valueOf(String name) {
            return Enum.valueOf(Hello.class, name);
        }
    }


    А внутри Enum.valueOf обычный HashMap<String, Hello>, где ключом является имя константы, а значением соответствующий инстанс класса Hello. Не могу согласиться, что этот вариант плох с точки зрения оптимизации.

    Но так как я знаю, что константы в enum это анонимные классы

    Это не так. Константы - это конкретные инстансы вашего enum класса, а не инстансы анонимных наследников от него.

    Получается мне действительно прийдется перекрывать эти переменные повторным объявлением для разрыва связи с предком?

    Не очень понял суть вопроса. Чтобы разорвать связь с предком нужно просто удалить наследование от него.
    Ответ написан
    2 комментария
  • Можно ли пройти весь курс javarush, решая задачи?

    @Araya
    Да, если решать все задачи, материя будет в избытке (по крайней мере так было с года полтора назад)
    Ответ написан
    Комментировать
  • Как безболезненно перейти с Python на Rust?

    vabka
    @vabka
    Токсичный шарпист
    Как безболезненно перейти с Python на Rust?

    Учиться, учиться, учиться.
    1) Python медленный

    Питон на удивление быстрый, особенно если использовать PyPy, а сильные тормоза возникают только в особых случаях.
    2) В python нет адекватного управления памятью

    Автоматический GC - это один из самых адекватных способов управления памятью, который только придумывало человечество.
    3) В python мне приходится испльзовать кучу мегабайт библиотек (я чувствую себя тупым и бесполезным при импортировании библеотек)

    А вы импортируйте их с мыслью "я не хочу тратить кучу времени на реализацию этого всего с нуля"
    В расте вам точно также придётся импортировать кучу библиотек, как и в любом другом языке, где есть библиотеки.
    4) Python кажется игрушечным языком

    Зря так думаете. Python очень мощный.
    5) Python не подходит род микроконтроллеры (micropython - просто игрушка)

    Раст+МК для новичков тоже очень страшная вещь - посмотрите на вопросы от товарища eegmak, например, чтобы в этом убедиться.
    Micropython - вполне себе production ready инструмент для тех случаев, когда его хватает, и не нужно ужиматься в очень дешёвые чипы.
    6) Проблемы из-за GIL'а

    С какими именно проблемами вы столкнулись на практике?)
    Скорее всего, их можно решить и менее радикальными методами.

    ИМХО: вы услышали от кого-то что Rust-топ язык, а Python - игрушечный, а настоящие программисты используют ручное управление памятью и сами реализовывают всякие сложные алгоритмы и протоколы.
    Хотя обычно ещё пишут, что настоящие программисты пишут только на C, только в виме, и никогда не ищут ответы на русскоязычных форумах.

    Если я прав - задумайтесь ещё раз, какую именно вашу проблему может решить раст, которую не может решить Python.

    Если я вас не отговорил - берите rustbook (лучше способа не придумали ещё).

    Если хочется перейти на другой язык, не обязательно раст - посмотрите в сторону других языков со сборкой мусора - например C#, Go, или D. Их все можно использовать в том числе и на МК, с разной степенью извращений.
    Ответ написан
  • Как использовать "is" в предикатах?

    vabka
    @vabka
    Токсичный шарпист
    Единого стандарта нет, но часто можно от is отказаться вообще, и оставить только:
    queueOverflow
    queueEmpty
    Ответ написан
    1 комментарий