@@ -760,9 +760,25 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
760
760
/// Returns a copy of `v`.
761
761
#[ inline]
762
762
fn to_owned ( & self ) -> ~[ T ] {
763
- let mut result = with_capacity ( self . len ( ) ) ;
764
- for e in self . iter ( ) {
765
- result. push ( ( * e) . clone ( ) ) ;
763
+ let len = self . len ( ) ;
764
+ let mut result = with_capacity ( len) ;
765
+ // Unsafe code so this can be optimised to a memcpy (or something
766
+ // similarly fast) when T is Copy. LLVM is easily confused, so any
767
+ // extra operations during the loop can prevent this optimisation
768
+ unsafe {
769
+ let mut i = 0 ;
770
+ let p = result. as_mut_ptr ( ) ;
771
+ // Use try_finally here otherwise the write to length
772
+ // inside the loop stops LLVM from optimising this.
773
+ try_finally (
774
+ & mut i, ( ) ,
775
+ |i, ( ) | while * i < len {
776
+ mem:: move_val_init (
777
+ & mut ( * p. offset ( * i as int ) ) ,
778
+ self . unsafe_ref ( * i) . clone ( ) ) ;
779
+ * i += 1 ;
780
+ } ,
781
+ |i| result. set_len ( * i) ) ;
766
782
}
767
783
result
768
784
}
@@ -2584,7 +2600,8 @@ pub mod bytes {
2584
2600
impl < A : Clone > Clone for ~[ A ] {
2585
2601
#[ inline]
2586
2602
fn clone ( & self ) -> ~[ A ] {
2587
- self . iter ( ) . map ( |item| item. clone ( ) ) . collect ( )
2603
+ // Use the fast to_owned on &[A] for cloning
2604
+ self . as_slice ( ) . to_owned ( )
2588
2605
}
2589
2606
2590
2607
fn clone_from ( & mut self , source : & ~[ A ] ) {
0 commit comments