如何将人造丝的 .par_iter() 与泛型向量一起使用?
How to use rayon's .par_iter() with a vector of generics?
这是一个人为的例子,但我相信如果我能做到这一点,我就可以将它应用到我的具体案例中。
extern crate num;
extern crate rayon;
use rayon::prelude::*;
use num::Float;
fn sqrts<T: Float>(floats: &Vec<T>) -> Vec<T> {
floats.par_iter().map(|f| f.sqrt()).collect()
}
fn main() {
let v = vec![1.0, 4.0, 9.0, 16.0, 25.0];
println!("{:?}", sqrts(&v));
}
此错误在编译时出现 "the method par_iter
exists but the following trait bounds were not satisfied: &std::vec::Vec<T> : rayon::par_iter::IntoParallelIterator
"。如果我使用 iter
而不是 par_iter
或者如果我切换到使用 f32
或 f64
而不是泛型,代码工作正常。
我该怎么做才能在泛型向量上使用 par_iter
? IntoParallelIterator
特征是要由最终用户实现的吗?我该怎么做?
首先,阅读。那么...
查看 IntoParallelIterator
的实现者:
impl<'data, T: Sync + 'data> IntoParallelIterator for &'data [T]
添加 Sync
绑定解决了这个问题。 Rayon 通过可能使用多个线程来工作,但是您的原始 T
不保证共享或线程之间是否安全!这是第二次出现:
error: no method named `collect` found for type `rayon::par_iter::map::Map<rayon::par_iter::slice::SliceIter<'_, T>, rayon::par_iter::map::MapFn<[closure@src/main.rs:7:27: 7:39]>>` in the current scope
--> src/main.rs:7:41
|
7 | floats.par_iter().map(|f| f.sqrt()).collect()
| ^^^^^^^
|
= note: the method `collect` exists but the following trait bounds were not satisfied: `rayon::par_iter::map::MapFn<[closure@src/main.rs:7:27: 7:39]> : rayon::par_iter::map::MapOp<&_>`, `rayon::par_iter::map::Map<rayon::par_iter::slice::SliceIter<'_, T>, rayon::par_iter::map::MapFn<[closure@src/main.rs:7:27: 7:39]>> : std::iter::Iterator`
签出 collect
:
fn collect<C>(self) -> C
where C: FromParallelIterator<Self::Item>
我们可以看到目标类型需要实现FromParallelIterator
:
impl<T> FromParallelIterator<T> for Vec<T> where T: Send
因此,添加两个边界允许它编译:
fn sqrts<T: Float + Send + Sync>(floats: &[T]) -> Vec<T>
这是一个人为的例子,但我相信如果我能做到这一点,我就可以将它应用到我的具体案例中。
extern crate num;
extern crate rayon;
use rayon::prelude::*;
use num::Float;
fn sqrts<T: Float>(floats: &Vec<T>) -> Vec<T> {
floats.par_iter().map(|f| f.sqrt()).collect()
}
fn main() {
let v = vec![1.0, 4.0, 9.0, 16.0, 25.0];
println!("{:?}", sqrts(&v));
}
此错误在编译时出现 "the method par_iter
exists but the following trait bounds were not satisfied: &std::vec::Vec<T> : rayon::par_iter::IntoParallelIterator
"。如果我使用 iter
而不是 par_iter
或者如果我切换到使用 f32
或 f64
而不是泛型,代码工作正常。
我该怎么做才能在泛型向量上使用 par_iter
? IntoParallelIterator
特征是要由最终用户实现的吗?我该怎么做?
首先,阅读
查看 IntoParallelIterator
的实现者:
impl<'data, T: Sync + 'data> IntoParallelIterator for &'data [T]
添加 Sync
绑定解决了这个问题。 Rayon 通过可能使用多个线程来工作,但是您的原始 T
不保证共享或线程之间是否安全!这是第二次出现:
error: no method named `collect` found for type `rayon::par_iter::map::Map<rayon::par_iter::slice::SliceIter<'_, T>, rayon::par_iter::map::MapFn<[closure@src/main.rs:7:27: 7:39]>>` in the current scope
--> src/main.rs:7:41
|
7 | floats.par_iter().map(|f| f.sqrt()).collect()
| ^^^^^^^
|
= note: the method `collect` exists but the following trait bounds were not satisfied: `rayon::par_iter::map::MapFn<[closure@src/main.rs:7:27: 7:39]> : rayon::par_iter::map::MapOp<&_>`, `rayon::par_iter::map::Map<rayon::par_iter::slice::SliceIter<'_, T>, rayon::par_iter::map::MapFn<[closure@src/main.rs:7:27: 7:39]>> : std::iter::Iterator`
签出 collect
:
fn collect<C>(self) -> C
where C: FromParallelIterator<Self::Item>
我们可以看到目标类型需要实现FromParallelIterator
:
impl<T> FromParallelIterator<T> for Vec<T> where T: Send
因此,添加两个边界允许它编译:
fn sqrts<T: Float + Send + Sync>(floats: &[T]) -> Vec<T>