Skip to content

Commit e87ff2a

Browse files
committed
https://github.com/Rust-for-Linux/linux/pull/356#issuecomment-859621440
By Bjorn3: With opt-level=0 you can't do any realistic benchmarks. The compiler won't optimize away any zero-cost abstractions. For example for item in vec.iter() { ... } can be faster than while i < vec.len() { ...; i+=1; } with optimizations due to no bounds checking, but without optimizations it is likely much slower. black_box calls didn't help as you likely passed a function item and not function pointer through the black box. This means that it is still known which function is called based on the type of the function item. Taking fn() -> Result<V, E> instead of F: Fn() -> Result<V, E> fixes this issue. Replacing the rt = match ... with rt += match ... inside use_result is also necessary to prevent optimizing away the match.
1 parent 3920655 commit e87ff2a

File tree

2 files changed

+19
-27
lines changed

2 files changed

+19
-27
lines changed

Cargo.toml

-9
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,5 @@ edition = "2018"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

8-
[profile.dev]
9-
opt-level = 0
10-
11-
[profile.release]
12-
opt-level = 0
13-
14-
[profile.bench]
15-
opt-level = 0
16-
178

189
[dependencies]

src/main.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
#![feature(test)]
1+
#![feature(test, bench_black_box)]
22

3-
use core::num::{NonZeroI16, NonZeroI32};
43
extern crate test;
54

5+
use std::hint::black_box;
6+
use std::num::{NonZeroI16, NonZeroI32};
7+
68
#[derive(Clone, Copy, PartialEq, Eq)]
79
pub struct ErrorNzi32(NonZeroI32);
810
pub struct ErrorNzi16(NonZeroI16);
@@ -67,13 +69,12 @@ mod bench {
6769
}
6870
}
6971

70-
fn use_result<F, V, E>(n: i32, f: F) -> (i32, Result<V, E>)
71-
where
72-
F: Fn() -> Result<V, E>,
72+
#[inline(never)]
73+
fn use_result<V, E>(n: i32, f: fn() -> Result<V, E>) -> (i32, Result<V, E>)
7374
{
7475
let mut rt :i32 = 0;
7576
for _ in 0..n {
76-
rt = match f() {
77+
rt += match f() {
7778
Ok(_) => 0,
7879
Err(_) => -1,
7980
};
@@ -84,62 +85,62 @@ mod bench {
8485

8586
#[bench]
8687
fn bench_nzi32_100(b: &mut Bencher) {
87-
b.iter(|| use_result(100, return_nzi32));
88+
b.iter(|| use_result(100, black_box(return_nzi32)));
8889
}
8990

9091
#[bench]
9192
fn bench_nzi32_10000(b: &mut Bencher) {
92-
b.iter(|| use_result(10000, return_nzi32));
93+
b.iter(|| use_result(10000, black_box(return_nzi32)));
9394
}
9495

9596
#[bench]
9697
fn bench_nzi32_1000000(b: &mut Bencher) {
97-
b.iter(|| use_result(1000000, return_nzi32));
98+
b.iter(|| use_result(1000000, black_box(return_nzi32)));
9899
}
99100

100101
#[bench]
101102
fn bench_nzi16_100(b: &mut Bencher) {
102-
b.iter(|| use_result(100, return_nzi16));
103+
b.iter(|| use_result(100, black_box(return_nzi16)));
103104
}
104105

105106
#[bench]
106107
fn bench_nzi16_10000(b: &mut Bencher) {
107-
b.iter(|| use_result(10000, return_nzi16));
108+
b.iter(|| use_result(10000, black_box(return_nzi16)));
108109
}
109110

110111
#[bench]
111112
fn bench_nzi16_1000000(b: &mut Bencher) {
112-
b.iter(|| use_result(1000000, return_nzi16));
113+
b.iter(|| use_result(1000000, black_box(return_nzi16)));
113114
}
114115

115116
#[bench]
116117
fn bench_i32_100(b: &mut Bencher) {
117-
b.iter(|| use_result(100, return_i32));
118+
b.iter(|| use_result(100, black_box(return_i32)));
118119
}
119120

120121
#[bench]
121122
fn bench_i32_10000(b: &mut Bencher) {
122-
b.iter(|| use_result(10000, return_i32));
123+
b.iter(|| use_result(10000, black_box(return_i32)));
123124
}
124125

125126
#[bench]
126127
fn bench_i32_1000000(b: &mut Bencher) {
127-
b.iter(|| use_result(1000000, return_i32));
128+
b.iter(|| use_result(1000000, black_box(return_i32)));
128129
}
129130

130131
#[bench]
131132
fn bench_i16_100(b: &mut Bencher) {
132-
b.iter(|| use_result(100, return_i16));
133+
b.iter(|| use_result(100, black_box(return_i16)));
133134
}
134135

135136
#[bench]
136137
fn bench_i16_10000(b: &mut Bencher) {
137-
b.iter(|| use_result(10000, return_i16));
138+
b.iter(|| use_result(10000, black_box(return_i16)));
138139
}
139140

140141
#[bench]
141142
fn bench_i16_1000000(b: &mut Bencher) {
142-
b.iter(|| use_result(1000000, return_i16));
143+
b.iter(|| use_result(1000000, black_box(return_i16)));
143144
}
144145
}
145146

0 commit comments

Comments
 (0)