Pull to refresh
266
Андрей Дмитриев@AndreyDmitriev

Пользователь

1,1
Rating
113
Subscribers
Send message

— А о чём, товарищи, эта книга? — осведомился он.

— Да ни о чём, — сказал я.

Купите мощный UV фонарь, где-то 400 нм вроде, выйдите на поиски вечером и попробуйте поискать по флуоресценции.

замедление времени — всё это стоит на обычном школьном синусе, которому угол сделали мнимым.

Ну то есть мы можем, пользуясь такими синусами честно и численно показать аномальное смещение перигелия Меркурия, которое 43 угловые секунды? Было бы любопытно взглянуть на расчёты.

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

Вот смотрите, допустим такой примитивный код, тут восемь строчек всего:

fn main() {
    let mut x = 10; // создаём изменяемую переменную x со значением 10
    add_one(&mut x);// передаём изменяемую ссылку на x (mutable borrow)
    println!("x after mod: {x}"); // выводим значение x после изменения
}

fn add_one(n: &mut i32) {
    *n += 1; // разыменовываем ссылку и увеличиваем значение на 1
}

Вначале при компиляции идёт стадия HIR (High‑Level IR) - преобразование в высоко-уровневое промежуточное представление. С некоторой натяжкой его можно назвать "препроцессор", тут разворачиваются макросы, код очищается от "сахара", вот что получится, это всё ещё Раст:

extern crate std;
#[attr = PreludeImport]
use std::prelude::rust_2024::*;
fn main() {
    let mut x =
        10; // создаём изменяемую переменную x со значением 10
    add_one(&mut x); // передаём изменяемую ссылку на x (mutable borrow)
    // выводим значение x после изменения

    // разыменовываем ссылку и увеличиваем значение на 1
    {
        ::std::io::_print({
                super let args = (&x,);
                super let args = [format_argument::new_display(args.0)];
                unsafe {
                    format_arguments::new(b"\rx after mod: \xc0\x01\n\x00",
                        &args)
                }
            });
    };
}
fn add_one(n: &'_ mut i32) { *n += 1; }

Затем идёт вторая стадия, THIR (Typed High‑Level IR), тоже высокоуровневая, тут я только кусочек покажу:

DefId(0:4 ~ r_test[ee7e]::add_one):
params: [
    Param {
        ty: &'{erased} mut i32
        ty_span: Some(src\main.rs:7:15: 7:23 (#0))
        self_kind: None
        hir_id: Some(HirId(DefId(0:4 ~ r_test[ee7e]::add_one).1))
        param: Some( 
            Pat {
                ty: &'{erased} mut i32
                span: src\main.rs:7:12: 7:13 (#0)
                kind: PatKind {
                    Binding {
                        name: "n"
                        mode: BindingMode(No, Not)
Так-то там восемьсот(!) с лишним строк
DefId(0:3 ~ r_test[ee7e]::main):
params: [
]
body:
    Expr {
        ty: ()
        temp_scope_id: 54
        span: src\main.rs:1:11: 5:2 (#0)
        kind: 
            Scope {
                region_scope: Node(54)
                hir_id: HirId(DefId(0:3 ~ r_test[ee7e]::main).54)
                value:
                    Expr {
                        ty: ()
                        temp_scope_id: 54
                        span: src\main.rs:1:11: 5:2 (#0)
                        kind: 
                            Block {
                                targeted_by_break: false
                                span: src\main.rs:1:11: 5:2 (#0)
                                region_scope: Node(1)
                                safety_mode: Safe
                                stmts: [
                                    Stmt {
                                        kind: Let {
                                            remainder_scope: Remainder { block: 1, first_statement_index: 0}
                                            init_scope: Node(2)
                                            pattern: 
                                                Pat {
                                                    ty: i32
                                                    span: src\main.rs:2:9: 2:14 (#0)
                                                    kind: PatKind {
                                                        Binding {
                                                            name: "x"
                                                            mode: BindingMode(No, Mut)
                                                            var: LocalVarId(HirId(DefId(0:3 ~ r_test[ee7e]::main).5))
                                                            ty: i32
                                                            is_primary: true
                                                            is_shorthand: false
                                                            subpattern: None
                                                        }
                                                    }
                                                }
                                            ,
                                            initializer: Some(
                                                Expr {
                                                    ty: i32
                                                    temp_scope_id: 3
                                                    span: src\main.rs:2:17: 2:19 (#0)
                                                    kind: 
                                                        Scope {
                                                            region_scope: Node(3)
                                                            hir_id: HirId(DefId(0:3 ~ r_test[ee7e]::main).3)
                                                            value:
                                                                Expr {
                                                                    ty: i32
                                                                    temp_scope_id: 3
                                                                    span: src\main.rs:2:17: 2:19 (#0)
                                                                    kind: 
                                                                        Literal( lit: Spanned { node: Int(Pu128(10), Unsuffixed), span: src\main.rs:2:17: 2:19 (#0) }, neg: false)

                                                                }
                                                        }
                                                }
                                            )
                                            else_block: None
                                            hir_id: HirId(DefId(0:3 ~ r_test[ee7e]::main).4)
                                            span: src\main.rs:2:5: 2:19 (#0)
                                        }
                                    }
                                    Stmt {
                                        kind: Expr {
                                            scope: Node(12)
                                            expr:
                                                Expr {
                                                    ty: ()
                                                    temp_scope_id: 6
                                                    span: src\main.rs:3:5: 3:20 (#0)
                                                    kind: 
                                                        Scope {
                                                            region_scope: Node(6)
                                                            hir_id: HirId(DefId(0:3 ~ r_test[ee7e]::main).6)
                                                            value:
                                                                Expr {
                                                                    ty: ()
                                                                    temp_scope_id: 6
                                         ... дальше Хабр не разрешает

Следом идёт средняя промежуточная стадия MIR (Mid‑Level Intermediate Representation), тут мы ближе к llvm, и как раз на этом этапе разбираются заимствования, владения, времена жизни, и Miri, кстати, работает как раз на этом уровне:

    let _11: &[core::fmt::rt::Argument<'_>; 1];
    let mut _12: &i32;
    scope 1 {
        debug x => _1;
        let _6: (&i32,);
        scope 2 {
            debug args => _6;
            let _8: [core::fmt::rt::Argument<'_>; 1];
            scope 3 {
                debug args => _8;
            }
        }
    }

    bb0: {
        _1 = const 10_i32;
        _3 = &mut _1;
        _2 = add_one(copy _3) -> [return: bb1, unwind continue];
    }
Полностью
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
// HINT: See also -Z dump-mir for MIR at specific points during compilation.
fn main() -> () {
    let mut _0: ();
    let mut _1: i32;
    let _2: ();
    let mut _3: &mut i32;
    let _4: ();
    let mut _5: std::fmt::Arguments<'_>;
    let mut _7: &i32;
    let mut _9: core::fmt::rt::Argument<'_>;
    let mut _10: &[u8; 27];
    let _11: &[core::fmt::rt::Argument<'_>; 1];
    let mut _12: &i32;
    scope 1 {
        debug x => _1;
        let _6: (&i32,);
        scope 2 {
            debug args => _6;
            let _8: [core::fmt::rt::Argument<'_>; 1];
            scope 3 {
                debug args => _8;
            }
        }
    }

    bb0: {
        _1 = const 10_i32;
        _3 = &mut _1;
        _2 = add_one(copy _3) -> [return: bb1, unwind continue];
    }

    bb1: {
        _7 = &_1;
        _6 = (move _7,);
        _12 = no_retag copy (_6.0: &i32);
        _9 = core::fmt::rt::Argument::<'_>::new_display::<i32>(copy _12) -> [return: bb2, unwind continue];
    }

    bb2: {
        _8 = [move _9];
        _10 = const b"\x16x after modification: \xc0\x01\n\x00";
        _11 = &_8;
        _5 = Arguments::<'_>::new::<27, 1>(move _10, copy _11) -> [return: bb3, unwind continue];
    }

    bb3: {
        _4 = std::io::_print(move _5) -> [return: bb4, unwind continue];
    }

    bb4: {
        return;
    }
}

alloc1 (size: 27, align: 1) {
    0x00 │ 16 78 20 61 66 74 65 72 20 6d 6f 64 69 66 69 63 │ .x after modific
    0x10 │ 61 74 69 6f 6e 3a 20 c0 01 0a 00                │ ation: ....
}

fn add_one(_1: &mut i32) -> () {
    debug n => _1;
    let mut _0: ();
    let mut _2: (i32, bool);

    bb0: {
        _2 = AddWithOverflow(copy (*_1), const 1_i32);
        assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (*_1), const 1_i32) -> [success: bb1, unwind continue];
    }

    bb1: {
        (*_1) = move (_2.0: i32);
        return;
    }
}

И лишь затем идёт собственно llvm, это четвёртая стадия, там видно как наша константа 10 с инкрементом "сфолдилась" в 11:

  call void @llvm.lifetime.start.p0(ptr nonnull %x)
  store i32 11, ptr %x, align 4 ; 11 
  call void @llvm.lifetime.start.p0(ptr nonnull %args)
; ...
  call void __print(ptr noundef, ...

.LLVM полностью:

LLVM
; ModuleID = 'r_test.decfb7566f1495f6-cgu.0'
source_filename = "r_test.decfb7566f1495f6-cgu.0"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"

@vtable.0 = private unnamed_addr constant <{ [24 x i8], ptr, ptr, ptr }> <{ [24 x i8] c"\00\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr @_RNSNvYNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0INtNtNtCsckEfzrs6Fp9_4core3ops8function6FnOnceuE9call_once6vtableCsj81e8EUiNGk_6r_test, ptr @_RNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0Csj81e8EUiNGk_6r_test, ptr @_RNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0Csj81e8EUiNGk_6r_test }>, align 8
@alloc_e5787bd0c3f1ea82bc1a90da9c1a53af = private unnamed_addr constant [27 x i8] c"\16x after modification: \C0\01\0A\00", align 1

; std::rt::lang_start::<()>
; Function Attrs: uwtable
define hidden noundef i64 @_RINvNtCscd1f6iWV66h_3std2rt10lang_startuECsj81e8EUiNGk_6r_test(ptr noundef nonnull %main, i64 noundef %argc, ptr noundef %argv, i8 noundef %sigpipe) unnamed_addr #0 {
start:
  %_7 = alloca [8 x i8], align 8
  call void @llvm.lifetime.start.p0(ptr nonnull %_7)
  store ptr %main, ptr %_7, align 8
; call std::rt::lang_start_internal
  %_0 = call noundef i64 @_RNvNtCscd1f6iWV66h_3std2rt19lang_start_internal(ptr noundef nonnull %_7, ptr noalias nofree noundef readonly align 8 captures(address, read_provenance) dereferenceable(48) @vtable.0, i64 noundef %argc, ptr noundef %argv, i8 noundef %sigpipe)
  call void @llvm.lifetime.end.p0(ptr nonnull %_7)
  ret i64 %_0
}

; std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
; Function Attrs: noinline uwtable
define internal fastcc void @_RINvNtNtCscd1f6iWV66h_3std3sys9backtrace28___rust_begin_short_backtraceFEuuECsj81e8EUiNGk_6r_test(ptr noundef nonnull readonly captures(none) %f) unnamed_addr #1 {
start:
  tail call void %f()
  tail call void asm sideeffect "", "~{memory}"() #6, !srcloc !4
  ret void
}

; std::rt::lang_start::<()>::{closure#0}
; Function Attrs: inlinehint uwtable
define internal noundef i32 @_RNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0Csj81e8EUiNGk_6r_test(ptr noalias nofree noundef readonly align 8 captures(none) dereferenceable(8) %_1) unnamed_addr #2 {
start:
  %_4 = load ptr, ptr %_1, align 8, !nonnull !5, !noundef !5
; call std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
  tail call fastcc void @_RINvNtNtCscd1f6iWV66h_3std3sys9backtrace28___rust_begin_short_backtraceFEuuECsj81e8EUiNGk_6r_test(ptr noundef nonnull %_4) #7
  ret i32 0
}

; <std::rt::lang_start<()>::{closure#0} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
; Function Attrs: inlinehint uwtable
define internal noundef i32 @_RNSNvYNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0INtNtNtCsckEfzrs6Fp9_4core3ops8function6FnOnceuE9call_once6vtableCsj81e8EUiNGk_6r_test(ptr noundef readonly captures(none) %_1) unnamed_addr #2 personality ptr @__CxxFrameHandler3 {
start:
  %0 = load ptr, ptr %_1, align 8, !nonnull !5, !noundef !5
; call std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
  tail call fastcc void @_RINvNtNtCscd1f6iWV66h_3std3sys9backtrace28___rust_begin_short_backtraceFEuuECsj81e8EUiNGk_6r_test(ptr noundef nonnull readonly %0) #7, !noalias !6
  ret i32 0
}

; r_test::main
; Function Attrs: uwtable
define hidden void @_RNvCsj81e8EUiNGk_6r_test4main() unnamed_addr #0 {
start:
  %args = alloca [16 x i8], align 8
  %x = alloca [4 x i8], align 4
  call void @llvm.lifetime.start.p0(ptr nonnull %x)
  store i32 11, ptr %x, align 4
  call void @llvm.lifetime.start.p0(ptr nonnull %args)
  store ptr %x, ptr %args, align 8
  %_6.sroa.4.0..sroa_idx = getelementptr inbounds nuw i8, ptr %args, i64 8
  store ptr @_RNvXs9_NtNtNtCsckEfzrs6Fp9_4core3fmt3num3implNtB9_7Display3fmt, ptr %_6.sroa.4.0..sroa_idx, align 8
; call std::io::stdio::_print
  call void @_RNvNtNtCscd1f6iWV66h_3std2io5stdio6__print(ptr noundef nonnull @alloc_e5787bd0c3f1ea82bc1a90da9c1a53af, ptr noundef nonnull %args)
  call void @llvm.lifetime.end.p0(ptr nonnull %args)
  call void @llvm.lifetime.end.p0(ptr nonnull %x)
  ret void
}

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(ptr captures(none)) #3

; std::rt::lang_start_internal
; Function Attrs: uwtable
declare noundef i64 @_RNvNtCscd1f6iWV66h_3std2rt19lang_start_internal(ptr noundef nonnull, ptr noalias nofree noundef readonly align 8 captures(address, read_provenance) dereferenceable(48), i64 noundef, ptr noundef, i8 noundef) unnamed_addr #0

; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(ptr captures(none)) #3

; <i32 as core::fmt::Display>::fmt
; Function Attrs: uwtable
declare noundef zeroext i1 @_RNvXs9_NtNtNtCsckEfzrs6Fp9_4core3fmt3num3implNtB9_7Display3fmt(ptr noalias nofree noundef readonly align 4 captures(address, read_provenance) dereferenceable(4), ptr noalias nofree noundef align 8 dereferenceable(24)) unnamed_addr #0

; std::io::stdio::_print
; Function Attrs: uwtable
declare void @_RNvNtNtCscd1f6iWV66h_3std2io5stdio6__print(ptr noundef nonnull, ptr noundef nonnull) unnamed_addr #0

declare i32 @__CxxFrameHandler3(...) unnamed_addr #4

define noundef i32 @main(i32 %0, ptr %1) unnamed_addr #5 {
top:
  %_7.i = alloca [8 x i8], align 8
  %2 = sext i32 %0 to i64
  call void @llvm.lifetime.start.p0(ptr nonnull %_7.i)
  store ptr @_RNvCsj81e8EUiNGk_6r_test4main, ptr %_7.i, align 8
; call std::rt::lang_start_internal
  %_0.i = call noundef i64 @_RNvNtCscd1f6iWV66h_3std2rt19lang_start_internal(ptr noundef nonnull %_7.i, ptr noalias nofree noundef readonly align 8 captures(address, read_provenance) dereferenceable(48) @vtable.0, i64 noundef %2, ptr noundef %1, i8 noundef 0)
  call void @llvm.lifetime.end.p0(ptr nonnull %_7.i)
  %3 = trunc i64 %_0.i to i32
  ret i32 %3
}

attributes #0 = { uwtable "target-cpu"="x86-64" "target-features"="+cx16,+sse,+sse2,+sse3,+sahf" }
attributes #1 = { noinline uwtable "target-cpu"="x86-64" "target-features"="+cx16,+sse,+sse2,+sse3,+sahf" }
attributes #2 = { inlinehint uwtable "target-cpu"="x86-64" "target-features"="+cx16,+sse,+sse2,+sse3,+sahf" }
attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #4 = { "target-cpu"="x86-64" }
attributes #5 = { "target-cpu"="x86-64" "target-features"="+cx16,+sse,+sse2,+sse3,+sahf" }
attributes #6 = { nounwind }
attributes #7 = { noinline }

!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}

!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 7, !"PIE Level", i32 2}
!2 = !{i32 7, !"uwtable", i32 2}
!3 = !{!"rustc version 1.99.0-nightly (375b1431b 2026-07-10)"}
!4 = !{i64 4735085480825446}
!5 = !{}
!6 = !{!7}
!7 = distinct !{!7, !8, !"_RNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0Csj81e8EUiNGk_6r_test: %_1"}
!8 = distinct !{!8, !"_RNCINvNtCscd1f6iWV66h_3std2rt10lang_startuE0Csj81e8EUiNGk_6r_test"}

На а дальше ассемблер, тут просто по итогу печатаем 11 в консоль, вот здесь:

	mov	dword ptr [rsp + 36], 11 загрузили 11
	lea	rax, [rsp + 36]
	mov	qword ptr [rsp + 40], rax
	lea	rax, [rip + Display3fmt]
	mov	qword ptr [rsp + 48], rax
	call __print ; напечатали

Ассемблер

полный листинг
	.def	@feat.00;
	.scl	3;
	.type	0;
	.endef
	.globl	@feat.00
@feat.00 = 0
	.intel_syntax noprefix
	.file	"r_test.f5a1b3f68eecb1a6-cgu.0"
	.def	_ZN3std2rt10lang_start17h28856b37936baaa7E;
	.scl	2;
	.type	32;
	.endef
	.section	.text,"xr",one_only,_ZN3std2rt10lang_start17h28856b37936baaa7E,unique,0
	.globl	_ZN3std2rt10lang_start17h28856b37936baaa7E
	.p2align	4
_ZN3std2rt10lang_start17h28856b37936baaa7E:
.seh_proc _ZN3std2rt10lang_start17h28856b37936baaa7E
	sub	rsp, 56
	.seh_stackalloc 56
	.seh_endprologue
	mov	rax, r8
	mov	r8, rdx
	mov	qword ptr [rsp + 48], rcx
	mov	byte ptr [rsp + 32], r9b
	lea	rdx, [rip + anon.e6415d161255c43dc2c05166e7cf7172.0]
	lea	rcx, [rsp + 48]
	mov	r9, rax
	call	_RNvNtCslk5dvTldH8g_3std2rt19lang_start_internal
	nop
	.seh_startepilogue
	add	rsp, 56
	.seh_endepilogue
	ret
	.seh_endproc

	.def	_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h3c899e35677daf87E;
	.scl	3;
	.type	32;
	.endef
	.section	.text,"xr",one_only,_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h3c899e35677daf87E,unique,1
	.p2align	4
_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h3c899e35677daf87E:
.seh_proc _ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h3c899e35677daf87E
	sub	rsp, 40
	.seh_stackalloc 40
	.seh_endprologue
	mov	rcx, qword ptr [rcx]
	call	_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h8d3554b6567cef64E
	xor	eax, eax
	.seh_startepilogue
	add	rsp, 40
	.seh_endepilogue
	ret
	.seh_endproc

	.def	_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h8d3554b6567cef64E;
	.scl	3;
	.type	32;
	.endef
	.section	.text,"xr",one_only,_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h8d3554b6567cef64E,unique,2
	.p2align	4
_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h8d3554b6567cef64E:
.seh_proc _ZN3std3sys9backtrace28__rust_begin_short_backtrace17h8d3554b6567cef64E
	sub	rsp, 40
	.seh_stackalloc 40
	.seh_endprologue
	call	rcx
	nop
	#APP
	#NO_APP
	.seh_startepilogue
	add	rsp, 40
	.seh_endepilogue
	ret
	.seh_endproc

	.def	_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17hdd5ea432718ad0c1E;
	.scl	3;
	.type	32;
	.endef
	.section	.text,"xr",one_only,_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17hdd5ea432718ad0c1E,unique,3
	.p2align	4
_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17hdd5ea432718ad0c1E:
.seh_proc _ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17hdd5ea432718ad0c1E
	sub	rsp, 40
	.seh_stackalloc 40
	.seh_endprologue
	mov	rcx, qword ptr [rcx]
	call	_ZN3std3sys9backtrace28__rust_begin_short_backtrace17h8d3554b6567cef64E
	xor	eax, eax
	.seh_startepilogue
	add	rsp, 40
	.seh_endepilogue
	ret
	.seh_endproc

	.def	_ZN6r_test4main17haba959300c4c510dE;
	.scl	2;
	.type	32;
	.endef
	.section	.text,"xr",one_only,_ZN6r_test4main17haba959300c4c510dE,unique,4
	.globl	_ZN6r_test4main17haba959300c4c510dE
	.p2align	4
_ZN6r_test4main17haba959300c4c510dE:
.seh_proc _ZN6r_test4main17haba959300c4c510dE
	sub	rsp, 56
	.seh_stackalloc 56
	.seh_endprologue
	mov	dword ptr [rsp + 36], 11
	lea	rax, [rsp + 36]
	mov	qword ptr [rsp + 40], rax
	lea	rax, [rip + _RNvXs9_NtNtNtCs9N2lWLRSIT9_4core3fmt3num3implNtB9_7Display3fmt]
	mov	qword ptr [rsp + 48], rax
	lea	rcx, [rip + anon.e6415d161255c43dc2c05166e7cf7172.1]
	lea	rdx, [rsp + 40]
	call	_RNvNtNtCslk5dvTldH8g_3std2io5stdio6__print
	nop
	.seh_startepilogue
	add	rsp, 56
	.seh_endepilogue
	ret
	.seh_endproc

	.def	main;
	.scl	2;
	.type	32;
	.endef
	.section	.text,"xr",one_only,main,unique,5
	.globl	main
	.p2align	4
main:
.seh_proc main
	sub	rsp, 56
	.seh_stackalloc 56
	.seh_endprologue
	mov	r9, rdx
	movsxd	r8, ecx
	lea	rax, [rip + _ZN6r_test4main17haba959300c4c510dE]
	mov	qword ptr [rsp + 48], rax
	mov	byte ptr [rsp + 32], 0
	lea	rdx, [rip + anon.e6415d161255c43dc2c05166e7cf7172.0]
	lea	rcx, [rsp + 48]
	call	_RNvNtCslk5dvTldH8g_3std2rt19lang_start_internal
	nop
	.seh_startepilogue
	add	rsp, 56
	.seh_endepilogue
	ret
	.seh_endproc

	.section	.rdata,"dr",one_only,anon.e6415d161255c43dc2c05166e7cf7172.0,unique,6
	.p2align	3, 0x0
anon.e6415d161255c43dc2c05166e7cf7172.0:
	.asciz	"\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\b\000\000\000\000\000\000"
	.quad	_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17hdd5ea432718ad0c1E
	.quad	_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h3c899e35677daf87E
	.quad	_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h3c899e35677daf87E

	.section	.rdata,"dr",one_only,anon.e6415d161255c43dc2c05166e7cf7172.1,unique,7
anon.e6415d161255c43dc2c05166e7cf7172.1:
	.asciz	"\026x after modification: \300\001\n"

Вот что происходит всего с восемью строчками кода. Я полагаю, что основное время затрачивается на этапе THIR, но как-то руки не доходили проверить, да и не знаю как.

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

Это первое, что пришло в голову, даже недочитав до этого места, ведь хорошо известно, что проект с сотней-другой крейтов при компиляции после cargo clean занимает многоядерник на всю катушку:

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

Да потому что "сварщицей" уже было — https://www.businessinsider.com/software-engineer-pivoted-to-welding-because-ai-happier-now-2026-3... Ждём теперь такую же историю про, ну не знаю, водительницу грузовика, что ли?

Вот это ей, наверное, больше помогло. чем Gemini

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

У моей супруги в Фиате 500 спорт стоит любопытный моторчик — Twin Air Turbo, объёмом 0.9 литра. Там всего два цилиндра, причём они работают синфазно (вот не спрашивайте, поджигается ли там смесь в двух сразу или поочерёдно, я всё-таки думаю, что поочерёдно). Чтобы всё это чудо не ходило ходуном, там вал с противовесами в обратную сторону крутят. На канале Ильдар автоподбор его разбирали, там владелец был недоволен динамикой, но его в тяжёлую машину 500L вкорячили, либо там ещё и 85 сил версия была до кучи. Но 105 сил лёгкому Фиату вполне хватает, в спорт режиме он за 10 секунд примерно до сотни разгоняется, и по автобану 200 из него выжать можно, что для литрового неплохо. А в эко-режиме он экономичный, если ехать аккуратно, то 4 c небольшим литра на сотню. Он старенький довольно, в 2011 получил награду "лучший мотор года". Звук при работе правда странный, почти как мотоцикл с погромыхивающими клапанами.

Мощно, спору нет. А разве голый кирпич не надо ничем снаружи облицовывать, он же вроде довольно пористый и влагу будет набирать будь здоров? В Гамбурге очень много "кирпичных" домов, это стиль такой, но если присмотреться, то там на самом деле не обычный кирпич, а "клинкер", типа специальный облицовочный, почти квадратный в сечении он как керамика обожжённая со слоем глазури, его обычно через слой теплоизоляции кладут.

С гитхабом тоже надо аккуратно, скажем тот же код LabVIEW (который графический) туда нечасто выкладывают просто потому, что гитхаб под него не слишком заточен и он просядет в рейтинге, опять же учёные не так часто гитхабом пользуются, так что долю того же MATLAB это тоже опустит немного. Тут что-то комбинированно-взвешенное надо.

Делал себе что-то похожее, когда учил французский, на LabVIEW правда. Но у меня были проблемы с восприятием на слух, так что я брал учебные тексты и диалоги с аудио рядом и делал воспроизведение по предложениям или словам с возможностью замедления воспроизведения (есть алгоритмы, позволяющие замедлить, но без изменения высоты тона). Правда с форматом не заморачивался, просто XML с маркерами времени, чтобы звук из wav брать и проигрывать. В принципе похожие программы есть, просто в каждой что-то да не устроило.

Я просто немного этой области "касаюсь" и вижу там всё больше тот же LabVIEW, вот ещё Фортран, и MATLAB/Octave/Maple, ну и Python в последнее время. Хотя возможно, моя выборка нерепрезентативна. Повод посмотреть на R повнимательнее, я никогда его не "трогал", честно говоря, хотя стараюсь быть в курсе и на всех из первой двадцатки что-то делал, кроме Ada и Swift, пожалуй.

Самое главное тут - LabVIEW с 32-го места переехал на 26-е, обогнав Julia и Kotlin, глядишь, так и в двадцатку войдёт! Вообще к этому рейтингу есть некоторые вопросы, я вот сильно не уверен, что R так уж популярен, но в общем топ 5 и так хорошо известен.

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

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

18кб это если собирать из расчёта что в системе есть рантайм. 

Вы невнимательно коммент прочитали, не 18 кб, а "на 18 кб меньше". У автора исполняемый файл 2001К или 2.049.024 байт, а если просто заменить таргет с 11 на 10 в csproj и собрать вот ровно той же командой dotnet publish -c Release -r win-x64, то будет 1967К или 2.013.696 байт, то есть на 34 кб меньше. А 18 кб - это после того, как я скроллбар туда добавил. Кстати, его ещё и upx пожать можно, он не потеряет работспособности, а станет меньше мегабайта - 884224 байт всего.

А вот тут пишут, что в последних версиях и это может не работать https://learn.microsoft.com/en-in/answers/questions/2263244/extendeduihovertime-is-not-working-anymore, хотя там также и метод через gpedit.msc предлагается, но я с планшета коммент пишу, завтра на работе проверю, любопытно.

Ещё есть the Ghidra Book за авторством Chris Eagle и Kara Nance, недавно вышло второе издание. В конце там небольшое приложение для тех, кто знаком с IDA. Основное отличие, что Гидра как бы проектно ориентированная, ну то есть вначале надо создать проект, а потом импортировать туда бинарники для анализа (в четвёртой главе всё детально расписано), а в Иде просто открыли и погнали.

Я эту книгу прочитал в тот момент, когда уже вёл рукописные заметки несколько лет (в большей степени как инбокс для системы GTD Дэвида Аллена), и таким образом получил подтверждение, что всё делаю правильно. После прочтения чуть подкорректировал систему и стало совсем хорошо.

тут странно, я ваш же код скомпилял под 10 (свежеустановленную) и получилось даже на 18 КБ меньше, что-то там лишнего прицепилось.

1
23 ...

Information

Rating
2,102-nd
Location
Ahrensburg, Schleswig-Holstein, Германия
Date of birth
Registered
Activity