【问题标题】:How could I avoid cloning the entirety of a large struct to send to a thread when only parts are needed? [closed]当只需要部分时,如何避免克隆整个大型结构以发送到线程? [关闭]
【发布时间】:2020-06-23 15:36:40
【问题描述】:

我的用例:

  • 我有一个大型复杂结构。
  • 我想拍摄这个结构的快照,以将其发送到线程进行计算。
  • 此结构中的许多大字段不需要计算。
  • 结构中的许多字段是部分必需的(一个字段可能是一个结构,而该结构中只有几个参数是必需的)。

目前我只需调用.clone() 并将整个结构的克隆传递给线程。

很难给出一个好的例子,但这是我目前的方法的一个总结:

use tokio::task;

fn main() {
    let compex_struct = ComplexStruct::new(...);
    // some extra async stuff I don't think is 100% neccessary to this question
    let future = async_function(compex_struct.clone()); // Ideally not cloning whole struct
    // some extra async stuff I don't think is 100% neccessary to this question
}

fn async_function(complex_struct:ComplexStruct) -> task::JoinHandle<_> {
    task::spawn_blocking(move || {
        // bunch of work, then return something
    })
}

我目前的工作想法是有一个单独的结构,例如ThreadData,它用ThreadData::new(ComplexStruct) 实例化并有效地克隆所需的字段。然后我将ThreadData 传递给线程。

这个问题的最佳解决方案是什么?

【问题讨论】:

  • 如果你的结构很复杂,有时你只需要它的一部分,它可能不是很 SRP,你可能还是应该重构你的代码。
  • 你的问题是“我如何不克隆我不需要的东西”,答案是“不要克隆你不需要的东西”。我看不出你希望从除此之外的答案中得到什么。
  • 一个想法可能是将您的一些“许多大字段”放在Arcs 后面,以便克隆结构变得相对便宜。与将整个结构放在Arc 中相比,这具有一些优势(例如,不同的结构可能共享其字段的子集)。如果需要,您可以使用.make_mut() 来获得写时复制语义。但将这个大结构重构为更易于管理的东西可能会更好。

标签: rust rust-tokio


【解决方案1】:

我想你已经回答了你自己的问题。 ? 如果您只是在寻找验证,我相信只重构所需的部分是一个好主意。您可能会找到简化代码的方法,但性能提升似乎是您的理由。我们看不到这方面的基准,但也许您想跟踪它。

这部分只是我的意见,但你可以用ThreadData::from() 代替ThreadData::new(),或者更好的是impl From&lt;ComplexStruct&gt; for ThreadData {}。如果它只有一个目的,那没关系,但如果 ThreadData 将在不同的上下文中使用,我喜欢保持“新”/“来自”函数可用于一般实例。否则我最终会得到Struct::from_this()Struct::from_that()Struct::from_some_random_input()。 ?

【讨论】:

    猜你喜欢
    • 2021-11-08
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多