如何修改集合而不使用它?

发布于 2025-01-09 10:55:02 字数 1138 浏览 1 评论 0原文

我想在返回集合之前就地修改它:

fn main() {
    println!("{:?}", compute()); // should print [[2, 1, 0], [5, 4, 3]]
}

// u8 is just a placeholder, so impl Copy is considered cheating :)
fn compute() -> Vec<Vec<u8>> {
    let a = vec![0, 1, 2];
    let b = vec![3, 4, 5];

    let mut result = Vec::new();
    result.push(a);
    result.push(b);

    // avoids allocations from:
    //
    // result.iter()
    //     .map(|r| {
    //         r.reverse()
    //         r
    //     })
    //     .collect::<Vec<_>>()
    result.into_iter().for_each(|mut r| r.reverse());

    // errors out: the collection was consumed the line above
    result
}

已经使用 Vec::new() 分配了一个集合,因此在这里分配第二个集合似乎是一种浪费。我假设这就是 .collect() 所做的。

  1. 如何避免过度分配?
  2. 有没有什么简单的方法可以知道发生了多少分配?在 golang 中,它就像 go test -bench=. 一样简单,但在 Rust 中我找不到类似的东西。

链接到游乐场

I want to modify a collection in place before returning it:

fn main() {
    println!("{:?}", compute()); // should print [[2, 1, 0], [5, 4, 3]]
}

// u8 is just a placeholder, so impl Copy is considered cheating :)
fn compute() -> Vec<Vec<u8>> {
    let a = vec![0, 1, 2];
    let b = vec![3, 4, 5];

    let mut result = Vec::new();
    result.push(a);
    result.push(b);

    // avoids allocations from:
    //
    // result.iter()
    //     .map(|r| {
    //         r.reverse()
    //         r
    //     })
    //     .collect::<Vec<_>>()
    result.into_iter().for_each(|mut r| r.reverse());

    // errors out: the collection was consumed the line above
    result
}

A collection was already allocated with Vec::new(), so allocating a second collection here seems like a waste. I am assuming that's what .collect() does.

  1. How do I avoid the allocation in excess?
  2. Is there any easy way to know how many allocations are happening? In golang it was as easy as go test -bench=., but I can't find anything similar when it comes to Rust.

Link to playground

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷弦 2025-01-16 10:55:02

您需要对每个内部向量使用 &mut ,因为您可以只使用 iter_mut ,它使用 &mut Self 代替外部向量的Self

// u8 is just a placeholder, so impl Copy is considered cheating :)
fn compute() -> Vec<Vec<u8>> {
    let a = vec![0, 1, 2];
    let b = vec![3, 4, 5];

    let mut result = Vec::new();
    result.push(a);
    result.push(b);

    result.iter_mut().for_each(|r| r.reverse());

    result
}

游乐场

You need to use a &mut to each of the inside vectors, for that you can just use iter_mut which uses &mut Self instead of Self for the outer vector.

// u8 is just a placeholder, so impl Copy is considered cheating :)
fn compute() -> Vec<Vec<u8>> {
    let a = vec![0, 1, 2];
    let b = vec![3, 4, 5];

    let mut result = Vec::new();
    result.push(a);
    result.push(b);

    result.iter_mut().for_each(|r| r.reverse());

    result
}

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文