Я бы хотел использовать filter_map()
вместо unwrap()
в map()
и filter()
, но при этом я вижу снижение производительности. Как мне написать код, используя 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
, который включает режим разблокировки.
output
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)
Я использую rustc 1.44.0-nightly (6dee5f112 2020-04-06)
на 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