Skip to content

Commit 5a7cd84

Browse files
committed
Speed up the fast path for assert_eq! and assert_ne!
Currently, the panic!() calls directly borrow the value bindings. This causes those bindings to always be initialized, i.e. they're initialized even before the values are even compared. This causes noticeable overhead in what should be a really cheap operation. By performing a reborrow of the value in the call to panic!(), we allow LLVM to optimize that code, so that the extra borrow only happens in the error case. We could achieve the same result by dereferencing the values passed to panic!(), as the format machinery borrows them anyway, but this causes assertions to fail to compile if one of the values is unsized, i.e. it would be a breaking change.
1 parent 4db2394 commit 5a7cd84

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/libcore/macros.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ macro_rules! assert_eq {
4545
match (&$left, &$right) {
4646
(left_val, right_val) => {
4747
if !(*left_val == *right_val) {
48+
// The reborrows below are intentional. Without them, the stack slot for the
49+
// borrow is initialized even before the values are compared, leading to a
50+
// noticeable slow down.
4851
panic!(r#"assertion failed: `(left == right)`
4952
left: `{:?}`,
50-
right: `{:?}`"#, left_val, right_val)
53+
right: `{:?}`"#, &*left_val, &*right_val)
5154
}
5255
}
5356
}
@@ -59,9 +62,12 @@ macro_rules! assert_eq {
5962
match (&($left), &($right)) {
6063
(left_val, right_val) => {
6164
if !(*left_val == *right_val) {
65+
// The reborrows below are intentional. Without them, the stack slot for the
66+
// borrow is initialized even before the values are compared, leading to a
67+
// noticeable slow down.
6268
panic!(r#"assertion failed: `(left == right)`
6369
left: `{:?}`,
64-
right: `{:?}`: {}"#, left_val, right_val,
70+
right: `{:?}`: {}"#, &*left_val, &*right_val,
6571
format_args!($($arg)+))
6672
}
6773
}
@@ -96,9 +102,12 @@ macro_rules! assert_ne {
96102
match (&$left, &$right) {
97103
(left_val, right_val) => {
98104
if *left_val == *right_val {
105+
// The reborrows below are intentional. Without them, the stack slot for the
106+
// borrow is initialized even before the values are compared, leading to a
107+
// noticeable slow down.
99108
panic!(r#"assertion failed: `(left != right)`
100109
left: `{:?}`,
101-
right: `{:?}`"#, left_val, right_val)
110+
right: `{:?}`"#, &*left_val, &*right_val)
102111
}
103112
}
104113
}
@@ -110,9 +119,12 @@ macro_rules! assert_ne {
110119
match (&($left), &($right)) {
111120
(left_val, right_val) => {
112121
if *left_val == *right_val {
122+
// The reborrows below are intentional. Without them, the stack slot for the
123+
// borrow is initialized even before the values are compared, leading to a
124+
// noticeable slow down.
113125
panic!(r#"assertion failed: `(left != right)`
114126
left: `{:?}`,
115-
right: `{:?}`: {}"#, left_val, right_val,
127+
right: `{:?}`: {}"#, &*left_val, &*right_val,
116128
format_args!($($arg)+))
117129
}
118130
}

0 commit comments

Comments
 (0)