如何使用 Rayon 检测整数总和的溢出?
How do I detect overflow on a sum of integers using Rayon?
有没有办法检测 Rayon 中的溢出并强制它崩溃而不是无限循环?
extern crate rayon;
use rayon::prelude::*;
fn main() {
let sample: Vec<u32> = (0..50000000).collect();
let sum: u32 = sample.par_iter().sum();
println!("{}",sum );
}
您正在寻找 ParallelIterator::try_reduce
。文档示例可以满足您的需求(以及更多):
use rayon::prelude::*;
// Compute the sum of squares, being careful about overflow.
fn sum_squares<I: IntoParallelIterator<Item = i32>>(iter: I) -> Option<i32> {
iter.into_par_iter()
.map(|i| i.checked_mul(i)) // square each item,
.try_reduce(|| 0, i32::checked_add) // and add them up!
}
assert_eq!(sum_squares(0..5), Some(0 + 1 + 4 + 9 + 16));
// The sum might overflow
assert_eq!(sum_squares(0..10_000), None);
// Or the squares might overflow before it even reaches `try_reduce`
assert_eq!(sum_squares(1_000_000..1_000_001), None);
专门针对您的示例:
extern crate rayon;
use rayon::prelude::*;
fn main() {
let sample: Vec<u32> = (0..50000000).collect();
let sum = sample
.into_par_iter()
.map(Some)
.try_reduce(
|| 0,
|a, b| a.checked_add(b)
);
println!("{:?}", sum);
}
collect
是不必要的低效率,但我暂时保留了它。
有没有办法检测 Rayon 中的溢出并强制它崩溃而不是无限循环?
extern crate rayon;
use rayon::prelude::*;
fn main() {
let sample: Vec<u32> = (0..50000000).collect();
let sum: u32 = sample.par_iter().sum();
println!("{}",sum );
}
您正在寻找 ParallelIterator::try_reduce
。文档示例可以满足您的需求(以及更多):
use rayon::prelude::*; // Compute the sum of squares, being careful about overflow. fn sum_squares<I: IntoParallelIterator<Item = i32>>(iter: I) -> Option<i32> { iter.into_par_iter() .map(|i| i.checked_mul(i)) // square each item, .try_reduce(|| 0, i32::checked_add) // and add them up! } assert_eq!(sum_squares(0..5), Some(0 + 1 + 4 + 9 + 16)); // The sum might overflow assert_eq!(sum_squares(0..10_000), None); // Or the squares might overflow before it even reaches `try_reduce` assert_eq!(sum_squares(1_000_000..1_000_001), None);
专门针对您的示例:
extern crate rayon;
use rayon::prelude::*;
fn main() {
let sample: Vec<u32> = (0..50000000).collect();
let sum = sample
.into_par_iter()
.map(Some)
.try_reduce(
|| 0,
|a, b| a.checked_add(b)
);
println!("{:?}", sum);
}
collect
是不必要的低效率,但我暂时保留了它。