Skip to content

Commit a56ed6e

Browse files
author
bors-servo
authored
Auto merge of #107 - RReverser:macro-non-copy, r=mbrubeck
Allow smallvec! with non-Copy items When count of items is smaller or equal than the target inline size, macro will use `SmallVec::push`, but when it's large enough, it passes data on to `vec!` macro for in-place heap allocation and then uses `SmallVec::from_vec`. This trick gives ~3.5x performance increase on `bench_macro_from_list` compared to `SmallVec::with_capacity`. Fixes #98. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/107) <!-- Reviewable:end -->
2 parents fcb1b7e + fb32eb2 commit a56ed6e

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,20 @@ use std::marker::PhantomData;
113113
114114
#[macro_export]
115115
macro_rules! smallvec {
116+
// count helper: transform any expression into 1
117+
(@one $x:expr) => (1usize);
116118
($elem:expr; $n:expr) => ({
117-
SmallVec::from_elem($elem, $n)
119+
$crate::SmallVec::from_elem($elem, $n)
118120
});
119121
($($x:expr),*$(,)*) => ({
120-
SmallVec::from_slice(&[$($x),*])
122+
let count = 0usize $(+ smallvec!(@one $x))*;
123+
let mut vec = $crate::SmallVec::new();
124+
if count <= vec.inline_size() {
125+
$(vec.push($x);)*
126+
vec
127+
} else {
128+
$crate::SmallVec::from_vec(vec![$($x,)*])
129+
}
121130
});
122131
}
123132

0 commit comments

Comments
 (0)