Rust 声称 DashMap into_par_iter 特征边界不满足

发布于 2025-01-17 03:57:59 字数 3863 浏览 4 评论 0原文

一段时间以来,我的 Rust 程序使用带有并行迭代器桥的 DashMap。这是一个主要的性能瓶颈,我刚刚发现,现在 DashMap 据说支持直接并行迭代。所以我更新了我的依赖包并更改了我的代码。现在我有了像这样的 DashMap

let families_by_location: DashMap<
    petgraph::graph::NodeIndex<usize>,
    Vec<&mut Family>,
    std::hash::BuildHasherDefault<FxHasher>,
> = DashMap::default();

families_by_location.into_par_iter().map(...).collect();

但是,这无法编译,令人惊讶的是,错误消息对我来说非常没有帮助。

error[E0599]: the method `into_par_iter` exists for struct `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>`, but its trait bounds were not satisfied
   --> src/lib.rs:442:10
    |
442 |         .into_par_iter()
    |          ^^^^^^^^^^^^^ method cannot be called on `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>` due to unsatisfied trait bounds
    |
   ::: /home/gereon/.cargo/registry/src/github.com-1ecc6299db9ec823/dashmap-5.2.0/src/lib.rs:67:1
    |
67  | pub struct DashMap<K, V, S = RandomState> {
    | -----------------------------------------
    | |
    | doesn't satisfy `_: rayon::iter::IntoParallelIterator`
    | doesn't satisfy `_: rayon::iter::ParallelIterator`
    |
    = note: the following trait bounds were not satisfied:
            `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`
            `&dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `&dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`
            `&mut dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `&mut dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `dispersal_model_rust` due to previous error

我还尝试了 families_by_location.par_iter_mut() 来解决有关特征边界的类似无用错误。

我不明白这个问题。 DashMap上的特征边界作为 IntoParallelIterator 是 K: Send + Eq + Hash ,V:发送,S:发送+克隆+BuildHasherKNodeIndex,其中 实现Send + Sync + Eq + Hash因为usizeFxHasher Builder 据说还支持 Send + Sync + Clone + BuildHasher,并且 VecSend + Sync 如果其对象类型是。现在我会理解如果 &mut Family 不是 Send,在线程之间发送可变指针听起来很危险。但是,类似的东西

let a: Vec<&mut Family> = families.par_iter_mut().collect();
let b: &dyn Sync = &a;

不会引发编译错误,因此看起来 Vec<&mut Family> 实际上是 Send + Sync

所以在我看来,DashMap: IntoParallelIterator 的特征边界已经满足,为什么我会收到 Rust 编译器错误?

For some time, my Rust program used a DashMap with a parallel iterator bridge. This was a major performance bottleneck, and I have just found that these days, DashMap supposedly supports direct parallel iteration. So I updated my dependency crates and changed my code. Now I have my DashMap<K, V, S> like this

let families_by_location: DashMap<
    petgraph::graph::NodeIndex<usize>,
    Vec<&mut Family>,
    std::hash::BuildHasherDefault<FxHasher>,
> = DashMap::default();

families_by_location.into_par_iter().map(...).collect();

However, this does not compile, and surprisingly, the error message is very unhelpful for me.

error[E0599]: the method `into_par_iter` exists for struct `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>`, but its trait bounds were not satisfied
   --> src/lib.rs:442:10
    |
442 |         .into_par_iter()
    |          ^^^^^^^^^^^^^ method cannot be called on `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>` due to unsatisfied trait bounds
    |
   ::: /home/gereon/.cargo/registry/src/github.com-1ecc6299db9ec823/dashmap-5.2.0/src/lib.rs:67:1
    |
67  | pub struct DashMap<K, V, S = RandomState> {
    | -----------------------------------------
    | |
    | doesn't satisfy `_: rayon::iter::IntoParallelIterator`
    | doesn't satisfy `_: rayon::iter::ParallelIterator`
    |
    = note: the following trait bounds were not satisfied:
            `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`
            `&dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `&dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`
            `&mut dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::ParallelIterator`
            which is required by `&mut dashmap::DashMap<NodeIndex<usize>, Vec<&mut Family>, BuildHasherDefault<rustc_hash::FxHasher>>: rayon::iter::IntoParallelIterator`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `dispersal_model_rust` due to previous error

I also tried families_by_location.par_iter_mut() for a similarly unhelpful error concerning trait bounds.

I don't understand the issue. The trait bounds on DashMap<K, V, S> being an IntoParallelIterator are K: Send + Eq + Hash, V: Send, S: Send + Clone + BuildHasher.
K is NodeIndex<usize>, which implements Send + Sync + Eq + Hash because usize does.
The FxHasher Builder supposedly also supports Send + Sync + Clone + BuildHasher, and Vec is Send + Sync if its object type is. Now I would understand it if &mut Family is not Send, sending around mutable pointers between threads sounds dangerous. However, something like

let a: Vec<&mut Family> = families.par_iter_mut().collect();
let b: &dyn Sync = &a;

does no throw a compilation error, so it seems that Vec<&mut Family> is actually Send + Sync.

So it seems to me that the trait bounds for DashMap<K, V, S>: IntoParallelIterator trait bounds are fulfilled, why do I get the Rust compiler error?

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

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

发布评论

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

评论(1

夜光 2025-01-24 03:57:59

我在搜索“parallel”时发现的关于 DashMap 问题跟踪器的旧评论在那里,向我指出激活人造丝功能是必要的。我这样做了,你瞧,我的代码编译了。

(我仍然发现不这样做时收到的错误消息非常令人困惑。)

虽然 dashmap 的 docs.rs 页面 指出

人造丝

<小时>

此功能标志不会启用其他功能。

该声明有点误导:正如 Kevin Reid 指出的那样,“与大多数 rustdoc 和 docs.rs 内容不同,除了启用其他功能标记之外,不会自动报告功能标记的用途。”因此,所有这些声明仅意味着激活 dashmap 的人造丝功能不会激活其他功能标志。

An old comment on the DashMap issue tracker, which I found when searching for “parallel” on there, pointed out to me that activating the rayon feature is necessary. I did, and lo and behold my code compiles.

(I still find the error message which I get when not doing it quite confusing.)

While the list of feature flags on dashmap's docs.rs page states

rayon


This feature flag does not enable additional features.

that statement is a bit misleading: As Kevin Reid pointed out, “unlike most of rustdoc and docs.rs content, there is no automatic reporting of what a feature flag does, except for enabling other feature flags.” So all this statement only means is that activating dashmap's rayon feature does not activate other feature flags.

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