微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

过度工程:在 Rust 中的 HashMap 键上使用引用借用?

如何解决过度工程:在 Rust 中的 HashMap 键上使用引用借用?

我正在制作一个搜索算法 (BFS/DFS) 来搜索游戏状态树。 我已经用 C 语言完成了这个东西,但我想知道 Rust 是否会更快,因为我一直想学习 Rust,所以我想我会试一试。

我正在尝试将这件事优化到过度工程的地步(我喜欢它,让我来吧),我用 C 语言做了一个我认为很酷的优化,但我不知道如何(/如果可能的话)在 Rust 中。

我的算法大纲是这样的:

Add the start state to a queue,and make a hashmap [State -> PrevIoUs State,Action]
// I use this hashmap to find the way back later,and to check if I have been in a state before.

Take a state S0 from the queue:
   for all possible actions,calculate next state S1:
      if S1 is already a key in the hashmap,continue
      and add [ S1 -> S0,action taken ] to the hashmap
      add S1 to the queue,...
   // some other stuff here to check when to stop

我在 C 中所做的优化之一是:我没有将状态结构数据复制到队列中,而是将指向哈希图中相同数据的指针(因为我只是将其添加到哈希图中)复制到队列中,这样我就不必复制状态数据,但队列只是由指向哈希图中相同数据的指针组成。

这在 C 中很容易运行,因为我有自己的 hashmap 实现,所以很容易制作一个函数来返回指向 hashmap 中正确数据的指针。

在 Rust 中,我现在有了这个:

// Add all possible moves to be searched through later
for m in possible_moves.iter() {
    if let Some(new_state) = popped.do_move(m) { // popped is S0 from my algorithm outline
        if backmap.contains_key(&new_state) { continue; }
        queue.push_back(new_state);
        backmap.insert(new_state,Wayback {
        prev_state: popped,did_move: m });
    }
}

但这意味着new_state数据被复制到队列和hashmap中。 我想知道是否有一种方法可以不在 Rust 中复制这些数据,比如我的 C 版本(或其他方式)。

我喜欢这个优化,因为我只是喜欢它的优化感觉,但在 Rust 的情况下也是因为现在这个副本意味着我有 #[derive(Clone,copy)] 高于我的所有结构,这不是很好的 imo,如果没有办法进行我过度设计的优化,但有一种方法不必派生来复制和克隆我仍然想知道的特征。

非常感谢您的帮助!

附言我知道这不是您的常规代码问题,从我的解释中可能不太清楚,所以如果对我的意思有任何疑问,我会尽快回答。

解决方法

我喜欢这种优化,因为我只是喜欢它的优化感觉,但在 Rust 的情况下也是因为现在这个副本意味着我在所有结构之上都有 #[derive(Clone,Copy)],这不是不错的我

取决于结构的大小……这真的很重要吗? Copy 只是一个 memcpy

如果没有办法进行我过度设计的优化,但有一种方法不必派生来复制和克隆特征,我仍然想知道。

这里的问题是 Rust 想要每个数据都有一个明确的静态所有者,但这在您的算法中并不存在:状态由地图和队列“拥有”。 “共享”不清楚所有权的方法是使用 Rc,但这会转化为堆分配(当它不是原子时,引用计数流量并不重要),如果 {{1 }}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。