Rust 是否检测到重复的闭包(例如在循环中定义的闭包)?

问题描述 投票:0回答:2

当我需要调用很多失败的函数时,我有时会把它们放在闭包中。 然后我

?
它们并捕获任何特殊变体(其他语言的异常机制)。

以下是我对https://www.codewars.com/kata/5a090c4e697598d0b9000004/train/rust的解决方案

use std::collections::VecDeque;

fn solve(nums: &[i32]) -> Vec<i32> {
    let mut sorted = VecDeque::from_iter(nums.iter().copied());
    sorted.make_contiguous().sort();

    let mut rearranged = vec![];
    while let Some(()) =
        (||->Option<()>{
            rearranged.push(sorted.pop_back()?);
            rearranged.push(sorted.pop_front()?);
            Some(())
        })()
    {}
    rearranged
}

工作正常而且很干净,但我想知道, “Rust 是否会在每个while 循环

迭代中产生一个闭包
实例? (编辑:我添加了instance这个词) 如果是这样,它是否检测到产生的闭包是第一个闭包的“重复” 并优化重复?

如果能对闭包在循环内定义的情况进行一些理论上的考虑,我将不胜感激,就像上面那样。编译器做了哪些优化来避免数据重复?

loops rust closures compiler-optimization
2个回答
2
投票

最简单的检查方法是查看生成的程序集,当然是使用

--release

您的代码:

solve:
    pushq   %rbp
    pushq   %r15
    pushq   %r14
    pushq   %r13
    pushq   %r12
    pushq   %rbx
    subq    $200, %rsp
    movq    %rdi, %r8
    testq   %rdx, %rdx
    je  .LBB6_6
    movq    %rdx, %rbx
    movq    %r8, 128(%rsp)
    xorl    %ebp, %ebp
    movq    %rdx, %rax
    shrq    $61, %rax
    sete    %al
    jne .LBB6_128
    movq    %rsi, %r14
    leaq    (,%rbx,4), %rdi
    movb    %al, %bpl
    shlq    $2, %rbp
    movq    %rdi, 104(%rsp)
    movq    %rbp, %rsi
    callq   *__rust_alloc@GOTPCREL(%rip)
    testq   %rax, %rax
    je  .LBB6_129
    movq    %rbx, 40(%rsp)
    leaq    (%r14,%rbx,4), %r12
    addq    $-4, %r12
    movq    %r12, %rbp
    subq    %r14, %rbp
    movq    %rbp, %rbx
    shrq    $2, %rbx
    leaq    4(%rbp), %rdx
    andq    $-4, %rdx
    movq    %rax, (%rsp)
    movq    %rax, %rdi
    movq    %r14, %rsi
    callq   *memcpy@GOTPCREL(%rip)
    leaq    1(%rbx), %rax
    movq    %rax, 16(%rsp)
    cmpq    $80, %rbp
    jae .LBB6_7
    movl    $1, %r15d
    cmpq    %r14, %r12
    movq    (%rsp), %r12
    je  .LBB6_106
    movq    16(%rsp), %rax
    leaq    (%r12,%rax,4), %r8
    addq    $-4, %r8
    leaq    (%r12,%rbx,4), %rcx
    addq    $4, %rcx
    movq    $-2, %rbp
    jmp .LBB6_97

在变量中定义闭包(playground):

solve:
    pushq   %rbp
    pushq   %r15
    pushq   %r14
    pushq   %r13
    pushq   %r12
    pushq   %rbx
    subq    $200, %rsp
    movq    %rdi, %r8
    testq   %rdx, %rdx
    je  .LBB6_6
    movq    %rdx, %rbx
    movq    %r8, 128(%rsp)
    xorl    %ebp, %ebp
    movq    %rdx, %rax
    shrq    $61, %rax
    sete    %al
    jne .LBB6_128
    movq    %rsi, %r14
    leaq    (,%rbx,4), %rdi
    movb    %al, %bpl
    shlq    $2, %rbp
    movq    %rdi, 104(%rsp)
    movq    %rbp, %rsi
    callq   *__rust_alloc@GOTPCREL(%rip)
    testq   %rax, %rax
    je  .LBB6_129
    movq    %rbx, 40(%rsp)
    leaq    (%r14,%rbx,4), %r12
    addq    $-4, %r12
    movq    %r12, %rbp
    subq    %r14, %rbp
    movq    %rbp, %rbx
    shrq    $2, %rbx
    leaq    4(%rbp), %rdx
    andq    $-4, %rdx
    movq    %rax, (%rsp)
    movq    %rax, %rdi
    movq    %r14, %rsi
    callq   *memcpy@GOTPCREL(%rip)
    leaq    1(%rbx), %rax
    movq    %rax, 16(%rsp)
    cmpq    $80, %rbp
    jae .LBB6_7
    movl    $1, %r15d
    cmpq    %r14, %r12
    movq    (%rsp), %r12
    je  .LBB6_106
    movq    16(%rsp), %rax
    leaq    (%r12,%rax,4), %r8
    addq    $-4, %r8
    leaq    (%r12,%rbx,4), %rcx
    addq    $4, %rcx
    movq    $-2, %rbp
    jmp .LBB6_97    

它们是相同的。


0
投票

没有。这是不可能的,因为这意味着在运行时动态生成代码。闭包的定义忽略了控制流。

© www.soinside.com 2019 - 2024. All rights reserved.