[英]value of f32::NAN rust closure for omitting 'NaN' values
我有以下關閉。
let ss = aa.iter().fold(0., |sum: f32,x| if *x != f32::NAN { sum + e } else { sum + 0. })
我試圖對所有省略向量f32::NAN
的值求和(如果向量中有幾個NaN
值)。
但是,我的返回給了我NaN
值,因為if *x != f32::NAN
條件似乎無效, if *x != f32::NAN
我的條件。 因為,以下閉包將產生原始向量,而不是忽略NaN
值。
let bb = aa.iter().filter(|x| **x != f32::NAN).map(|x| x)
我的問題是,如何在if
條件下匹配f32::NAN
值? 從更廣泛的角度來看,如何在向量中忽略NaN
值?
您不能以這種方式檢查NaN,因為NaN == NaN
值為false
。 使用f32::is_nan
代替。 此外,您可以使用Iterator::filter
過濾掉迭代器的元素,並使用Iterator::sum
求和所有值。
這將產生以下代碼( Playground ):
let aa = [3.14f32, std::f32::NAN, 2.71, 27.99];
let ss = aa.iter()
.filter(|n| !n.is_nan())
.sum::<f32>();
println!("{}", ss);
在Warren Weckesser
的正確指導下, Warren Weckesser
使封堵工作。
這是針對可能需要的人的解決方案。
let ss = aa.iter().fold(0., |sum: f32, x| if x.is_nan() { sum + 0. } else { sum + x });
或者,
let ss = aa.iter().fold(0., |sum: f32, x| if x.is_nan() { sum } else { sum + x });
如果有人關心不必要的+
操作。
性能比較
extern crate rand;
use rand::Rng;
fn main() {
let mut a [f32; 1000] = [0.; 1000];
for i in 0..1000 {
a[i] = rand::thread_rng().gen_range(1,11);
}
}
方法-I:
let ss = a.iter()
.filter(|n| !n.is_nan())
.sum::<f32>();
Callgrind
>> cargo profiler callgrind -n 10
Compiling playground in debug mode...
Profiling playground with callgrind...
Total Instructions...3,959,454
177,532 (4.5%) isaac64.rs:rand::prng::isaac64::Isaac64Rng::isaac64
-----------------------------------------------------------------------
121,742 (3.1%) memmove-vec-unaligned-erms.S:memcpy@GLIBC_2.2.5
-----------------------------------------------------------------------
104,224 (2.6%) dl-lookup.c:do_lookup_x
-----------------------------------------------------------------------
102,982 (2.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
99,660 (2.5%) intrinsics.rs:core::intrinsics::copy_nonoverlapping
-----------------------------------------------------------------------
76,555 (1.9%) strcmp.S:strcmp
-----------------------------------------------------------------------
72,997 (1.8%) local.rs:_..std..thread..local..LocalKey..T....::try_with
-----------------------------------------------------------------------
72,063 (1.8%) ptr.rs:_..core..ptr..NonNull..T....::as_ref
-----------------------------------------------------------------------
70,028 (1.8%) rc.rs:alloc::rc::RcBoxPtr::strong
-----------------------------------------------------------------------
62,000 (1.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
方法-II:
let ss = a.iter()
.fold(0., |sum: f32, x| if x.is_nan() { sum } else { sum + x });
Callgrind
>> cargo profiler callgrind -n 10
Compiling playground in debug mode...
Profiling playground with callgrind...
Total Instructions...3,938,312
177,532 (4.5%) isaac64.rs:rand::prng::isaac64::Isaac64Rng::isaac64
-----------------------------------------------------------------------
121,766 (3.1%) memmove-vec-unaligned-erms.S:memcpy@GLIBC_2.2.5
-----------------------------------------------------------------------
104,224 (2.6%) dl-lookup.c:do_lookup_x
-----------------------------------------------------------------------
102,982 (2.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
99,660 (2.5%) intrinsics.rs:core::intrinsics::copy_nonoverlapping
-----------------------------------------------------------------------
76,555 (1.9%) strcmp.S:strcmp
-----------------------------------------------------------------------
72,997 (1.9%) local.rs:_..std..thread..local..LocalKey..T....::try_with
-----------------------------------------------------------------------
72,063 (1.8%) ptr.rs:_..core..ptr..NonNull..T....::as_ref
-----------------------------------------------------------------------
70,028 (1.8%) rc.rs:alloc::rc::RcBoxPtr::strong
-----------------------------------------------------------------------
62,000 (1.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
從總指令來看,對於1000
元素數組, 方法II在運行時性能方面要好得多,比方法I少~20,000
條指令。 預期這種差異將積極地轉化為方法II的增強的運行時性能。 調查,差異源自何處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.