【发布时间】:2020-08-11 18:44:56
【问题描述】:
我想在map() 和filter() 中使用filter_map() 而不是unwrap(),但是这样做会降低性能。如何在不损失性能的情况下使用filter_map() 编写代码?为什么首先会出现性能损失?
src/lib.rs
use std::collections::HashMap;
pub enum Kind {
Square(Square),
Circle(Circle),
}
#[derive(Default, Copy, Clone)]
pub struct Circle {
a: u32,
b: u32,
c: u32,
d: u32,
}
#[derive(Default)]
pub struct Square {
a: u32,
b: Option<u32>,
c: Option<u32>,
d: Option<u32>,
e: Option<u32>,
}
impl Kind {
pub fn get_circle(&self) -> Option<&Circle> {
if let Kind::Circle(b) = self {
return Some(b);
}
None
}
}
benches/test.rs
#![feature(test)]
extern crate test;
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use test::Bencher;
use testing::Circle;
use testing::Kind;
use testing::Square;
fn get_bencher() -> HashMap<SocketAddr, Kind> {
let mut question = HashMap::new();
let square: Square = Default::default();
question.insert(
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0),
Kind::Square(square),
);
let circle: Circle = Default::default();
for n in 1..=10000 {
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), n);
question.insert(socket, Kind::Circle(circle));
}
question
}
#[bench]
fn bencher01(b: &mut Bencher) {
let question = get_bencher();
b.iter(|| {
question
.iter()
.map(|a| (a.0, a.1.get_circle()))
.filter_map(|(&a, b)| Some((a, b?)))
.collect::<Vec<_>>()
})
}
#[bench]
fn bencher02(b: &mut Bencher) {
let question = get_bencher();
b.iter(|| {
question
.iter()
.map(|a| (a.0, a.1.get_circle()))
.filter(|c| c.1.is_some())
.map(|d| (*d.0, d.1.unwrap()))
.collect::<Vec<_>>()
})
}
#[bench]
fn bencher03(b: &mut Bencher) {
let question = get_bencher();
b.iter(|| {
question
.iter()
.filter_map(|a| Some((*a.0, a.1.get_circle()?)))
.collect::<Vec<_>>()
})
}
}
使用 Rust nightly 和 cargo bench 运行这些测试,这会强制发布模式。
输出
running 3 tests
test tests::bencher01 ... bench: 201,978 ns/iter (+/- 12,787)
test tests::bencher02 ... bench: 89,004 ns/iter (+/- 6,204)
test tests::bencher03 ... bench: 238,569 ns/iter (+/- 6,004)
我在Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz Linux #### 5.6.4-arch1-1 #1 SMP PREEMPT Mon, 13 Apr 2020 12:21:19 +0000 x86_64 GNU/Linux 上使用rustc 1.44.0-nightly (6dee5f112 2020-04-06)
【问题讨论】:
-
你的分析器说什么是慢的部分?