From 2317840c147ba3f6a7403d80f140200e0df44668 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 23 Jun 2014 19:01:03 -0400 Subject: [PATCH 1/3] collections: minor cleanup --- src/libcollections/hash/sip.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs index 887b0fb0b8a..4fd98538af7 100644 --- a/src/libcollections/hash/sip.rs +++ b/src/libcollections/hash/sip.rs @@ -265,8 +265,6 @@ pub fn hash_with_keys>(k0: u64, k1: u64, value: &T) -> u64 { state.result() } - - #[cfg(test)] mod tests { use test::Bencher; From 1ea9991921d2969517e445230997b8771d84bdb4 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 23 Jun 2014 19:09:19 -0400 Subject: [PATCH 2/3] alloc: impl Default for Rc --- src/liballoc/rc.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index a3ca72f1547..e3127030842 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -27,6 +27,7 @@ use core::mem::transmute; use core::cell::Cell; use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; +use core::default::Default; use core::kinds::marker; use core::ops::{Deref, Drop}; use core::option::{Option, Some, None}; @@ -152,6 +153,13 @@ impl Clone for Rc { } } +impl Default for Rc { + #[inline] + fn default() -> Rc { + Rc::new(Default::default()) + } +} + impl PartialEq for Rc { #[inline(always)] fn eq(&self, other: &Rc) -> bool { **self == **other } From ab1bd3adf673ef7a515242a2dcc09ce360d41d9c Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 23 Jun 2014 19:27:54 -0400 Subject: [PATCH 3/3] core: optimize {option,result}::collect The bug #11084 causes these collect functions to run about twice as slow as they should because llvm is having trouble optimizing away the closure for some reason. This patch works around that performance bug by using a simple adapter iterator explicitly for capturing if the outer iterator returns an error. --- src/libcore/option.rs | 32 ++++++++++++++++++++++---------- src/libcore/result.rs | 32 ++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9748235e94a..8fb10fcca0c 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -587,20 +587,32 @@ impl ExactSize for Item {} /// ``` #[inline] pub fn collect>, V: FromIterator>(iter: Iter) -> Option { - // FIXME(#11084): This should be twice as fast once this bug is closed. - let mut iter = iter.scan(false, |state, x| { - match x { - Some(x) => Some(x), - None => { - *state = true; - None + // FIXME(#11084): This could be replaced with Iterator::scan when this + // performance bug is closed. + + struct Adapter { + iter: Iter, + found_none: bool, + } + + impl>> Iterator for Adapter { + #[inline] + fn next(&mut self) -> Option { + match self.iter.next() { + Some(Some(value)) => Some(value), + Some(None) => { + self.found_none = true; + None + } + None => None, } } - }); + } - let v: V = FromIterator::from_iter(iter.by_ref()); + let mut adapter = Adapter { iter: iter, found_none: false }; + let v: V = FromIterator::from_iter(adapter.by_ref()); - if iter.state { + if adapter.found_none { None } else { Some(v) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 6c163b79199..8cd56713ffb 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -585,20 +585,32 @@ impl Result { /// ``` #[inline] pub fn collect>, V: FromIterator>(iter: Iter) -> Result { - // FIXME(#11084): This should be twice as fast once this bug is closed. - let mut iter = iter.scan(None, |state, x| { - match x { - Ok(x) => Some(x), - Err(err) => { - *state = Some(err); - None + // FIXME(#11084): This could be replaced with Iterator::scan when this + // performance bug is closed. + + struct Adapter { + iter: Iter, + err: Option, + } + + impl>> Iterator for Adapter { + #[inline] + fn next(&mut self) -> Option { + match self.iter.next() { + Some(Ok(value)) => Some(value), + Some(Err(err)) => { + self.err = Some(err); + None + } + None => None, } } - }); + } - let v: V = FromIterator::from_iter(iter.by_ref()); + let mut adapter = Adapter { iter: iter, err: None }; + let v: V = FromIterator::from_iter(adapter.by_ref()); - match iter.state { + match adapter.err { Some(err) => Err(err), None => Ok(v), }