From 2afed31eccf0a5e2e996f2d1b3aa1ed79cb31821 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 8 Aug 2013 23:49:49 -0400 Subject: [PATCH 1/4] vec: optimize the Add implementation before: test add ... bench: 164 ns/iter (+/- 1) after: test add ... bench: 113 ns/iter (+/- 2) --- src/libstd/vec.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index c831dd70918..d626b8604db 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -561,7 +561,7 @@ fn idx(&self, index: uint) -> Option<&'self [T]> { #[cfg(not(test))] pub mod traits { - use super::Vector; + use super::*; use clone::Clone; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv}; @@ -686,17 +686,17 @@ fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() } impl<'self,T:Clone, V: Vector> Add for &'self [T] { #[inline] fn add(&self, rhs: &V) -> ~[T] { - let mut res = self.to_owned(); + let mut res = with_capacity(self.len() + rhs.as_slice().len()); + res.push_all(*self); res.push_all(rhs.as_slice()); res } } + impl> Add for ~[T] { #[inline] fn add(&self, rhs: &V) -> ~[T] { - let mut res = self.to_owned(); - res.push_all(rhs.as_slice()); - res + self.as_slice() + rhs.as_slice() } } } @@ -3662,4 +3662,13 @@ fn mut_iterator(bh: &mut BenchHarness) { } } } + + #[bench] + fn add(b: &mut BenchHarness) { + let xs: &[int] = [5, ..10]; + let ys: &[int] = [5, ..10]; + do b.iter() { + xs + ys; + } + } } From 768c9a43ab4c1fa53f21d1be30c72fde6b2367de Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 10 Aug 2013 13:32:05 -0400 Subject: [PATCH 2/4] str: optimize `with_capacity` before: test bench_with_capacity ... bench: 104 ns/iter (+/- 4) after: test bench_with_capacity ... bench: 56 ns/iter (+/- 1) --- src/libstd/str.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 26a00cca4c8..81c9cde312e 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -807,6 +807,7 @@ pub fn from_utf16(v: &[u16]) -> ~str { /// Allocates a new string with the specified capacity. The string returned is /// the empty string, but has capacity for much more. +#[cfg(stage0)] #[inline] pub fn with_capacity(capacity: uint) -> ~str { let mut buf = ~""; @@ -814,6 +815,16 @@ pub fn with_capacity(capacity: uint) -> ~str { buf } +/// Allocates a new string with the specified capacity. The string returned is +/// the empty string, but has capacity for much more. +#[cfg(not(stage0))] +#[inline] +pub fn with_capacity(capacity: uint) -> ~str { + unsafe { + cast::transmute(vec::with_capacity::<~[u8]>(capacity)) + } +} + /// As char_len but for a slice of a string /// /// # Arguments @@ -3700,7 +3711,7 @@ fn sum_len(v: &[S]) -> uint { #[cfg(test)] mod bench { use extra::test::BenchHarness; - use str; + use super::*; #[bench] fn is_utf8_100_ascii(bh: &mut BenchHarness) { @@ -3710,7 +3721,7 @@ fn is_utf8_100_ascii(bh: &mut BenchHarness) { assert_eq!(100, s.len()); do bh.iter { - str::is_utf8(s); + is_utf8(s); } } @@ -3719,7 +3730,7 @@ fn is_utf8_100_multibyte(bh: &mut BenchHarness) { let s = bytes!("πŒ€πŒ–πŒ‹πŒ„πŒ‘πŒ‰ΰΈ›ΰΈ£Ψ―ΩˆΩ„Ψ© Ψ§Ω„ΩƒΩˆΩŠΨͺΰΈ—ΰΈ¨ΰΉ„ΰΈ—ΰΈ’δΈ­εŽπ…πŒΏπŒ»π†πŒΉπŒ»πŒ°"); assert_eq!(100, s.len()); do bh.iter { - str::is_utf8(s); + is_utf8(s); } } @@ -3742,4 +3753,11 @@ fn map_chars_100_multibytes(bh: &mut BenchHarness) { s.map_chars(|c| ((c as uint) + 1) as char); } } + + #[bench] + fn bench_with_capacity(bh: &mut BenchHarness) { + do bh.iter { + with_capacity(100); + } + } } From 774c9aebb3ea7d1cf97bde948b6bdec4badec261 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 10 Aug 2013 13:42:53 -0400 Subject: [PATCH 3/4] move `strdup_uniq` lang item to std::str --- src/libstd/str.rs | 8 ++++++++ src/libstd/unstable/lang.rs | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 81c9cde312e..0b270edc534 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -959,6 +959,14 @@ pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str { ::cast::transmute(v) } + #[lang="strdup_uniq"] + #[cfg(not(test))] + #[allow(missing_doc)] + #[inline] + pub unsafe fn strdup_uniq(ptr: *u8, len: uint) -> ~str { + from_buf_len(ptr, len) + } + /// Create a Rust string from a null-terminated C string pub unsafe fn from_c_str(buf: *libc::c_char) -> ~str { let mut curr = buf; diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index 9e7ac1fd7db..f5074e08558 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -93,12 +93,6 @@ pub unsafe fn check_not_borrowed(a: *u8, borrowck::check_not_borrowed(a, file, line) } -#[lang="strdup_uniq"] -#[inline] -pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str { - str::raw::from_buf_len(ptr, len) -} - #[lang="annihilate"] pub unsafe fn annihilate() { ::cleanup::annihilate() From 83b3a0eaf166c5dc88eb0ab9b4b793a3694f680b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 11 Aug 2013 03:17:01 -0400 Subject: [PATCH 4/4] fix unused imports --- src/libstd/unstable/lang.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index f5074e08558..d8df967a45c 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -12,8 +12,7 @@ use c_str::ToCStr; use cast::transmute; -use libc::{c_char, c_uchar, c_void, size_t, uintptr_t}; -use str; +use libc::{c_char, c_void, size_t, uintptr_t}; use sys; use rt::task::Task; use rt::local::Local;