diff options
| author | bors <bors@rust-lang.org> | 2014-05-08 21:01:42 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-08 21:01:42 -0700 |
| commit | a990920c6fff9b762c3d0968ff0a5fdcce6d2b39 (patch) | |
| tree | 8b4cb2edb2e48660ca6e6c0f6a660951f00c1e02 /src/libstd/rt | |
| parent | c0a25e4fdc1fcdde8378b4177a6f06c58001a3be (diff) | |
| parent | dc30c483810ca0ee3641f4bab8e6f2a44a883fee (diff) | |
| download | rust-a990920c6fff9b762c3d0968ff0a5fdcce6d2b39.tar.gz rust-a990920c6fff9b762c3d0968ff0a5fdcce6d2b39.zip | |
auto merge of #13963 : kballard/rust/remove_owned_vec_from_iterator, r=pcwalton
With `~[T]` no longer growable, the `FromIterator` impl for `~[T]` doesn't make much sense. Not only that, but nearly everywhere it is used is to convert from a `Vec<T>` into a `~[T]`, for the sake of maintaining existing APIs. This turns out to be a performance loss, as it means every API that returns `~[T]`, even a supposedly non-copying one, is in fact doing extra allocations and memcpy's. Even `&[T].to_owned()` is going through `Vec<T>` first. Remove the `FromIterator` impl for `~[T]`, and adjust all the APIs that relied on it to start using `Vec<T>` instead. This includes rewriting `&[T].to_owned()` to be more efficient, among other performance wins. Also add a new mechanism to go from `Vec<T>` -> `~[T]`, just in case anyone truly needs that, using the new trait `FromVec`. [breaking-change]
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/args.rs | 43 | ||||
| -rw-r--r-- | src/libstd/rt/rtio.rs | 4 |
2 files changed, 25 insertions, 22 deletions
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index ac1692e6bb3..df0f1d8d449 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -21,6 +21,7 @@ //! FIXME #7756: This has a lot of C glue for lack of globals. use option::Option; +use vec::Vec; #[cfg(test)] use option::{Some, None}; #[cfg(test)] use realstd; #[cfg(test)] use realargs = realstd::rt::args; @@ -36,10 +37,10 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) } #[cfg(test)] pub unsafe fn cleanup() { realargs::cleanup() } /// Take the global arguments from global storage. -#[cfg(not(test))] pub fn take() -> Option<~[~[u8]]> { imp::take() } -#[cfg(test)] pub fn take() -> Option<~[~[u8]]> { +#[cfg(not(test))] pub fn take() -> Option<Vec<~[u8]>> { imp::take() } +#[cfg(test)] pub fn take() -> Option<Vec<~[u8]>> { match realargs::take() { - realstd::option::Some(a) => Some(a), + realstd::option::Some(v) => Some(unsafe{ ::cast::transmute(v) }), realstd::option::None => None, } } @@ -47,14 +48,14 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) } /// Give the global arguments to global storage. /// /// It is an error if the arguments already exist. -#[cfg(not(test))] pub fn put(args: ~[~[u8]]) { imp::put(args) } -#[cfg(test)] pub fn put(args: ~[~[u8]]) { realargs::put(args) } +#[cfg(not(test))] pub fn put(args: Vec<~[u8]>) { imp::put(args) } +#[cfg(test)] pub fn put(args: Vec<~[u8]>) { realargs::put(unsafe { ::cast::transmute(args) }) } /// Make a clone of the global arguments. -#[cfg(not(test))] pub fn clone() -> Option<~[~[u8]]> { imp::clone() } -#[cfg(test)] pub fn clone() -> Option<~[~[u8]]> { +#[cfg(not(test))] pub fn clone() -> Option<Vec<~[u8]>> { imp::clone() } +#[cfg(test)] pub fn clone() -> Option<Vec<~[u8]>> { match realargs::clone() { - realstd::option::Some(a) => Some(a), + realstd::option::Some(v) => Some(unsafe { ::cast::transmute(v) }), realstd::option::None => None, } } @@ -70,6 +71,7 @@ mod imp { use owned::Box; use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; use mem; + use vec::Vec; #[cfg(not(test))] use ptr::RawPtr; static mut global_args_ptr: uint = 0; @@ -87,15 +89,15 @@ mod imp { lock.destroy(); } - pub fn take() -> Option<~[~[u8]]> { + pub fn take() -> Option<Vec<~[u8]>> { with_lock(|| unsafe { let ptr = get_global_ptr(); let val = mem::replace(&mut *ptr, None); - val.as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone()) + val.as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone()) }) } - pub fn put(args: ~[~[u8]]) { + pub fn put(args: Vec<~[u8]>) { with_lock(|| unsafe { let ptr = get_global_ptr(); rtassert!((*ptr).is_none()); @@ -103,10 +105,10 @@ mod imp { }) } - pub fn clone() -> Option<~[~[u8]]> { + pub fn clone() -> Option<Vec<~[u8]>> { with_lock(|| unsafe { let ptr = get_global_ptr(); - (*ptr).as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone()) + (*ptr).as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone()) }) } @@ -117,13 +119,13 @@ mod imp { } } - fn get_global_ptr() -> *mut Option<Box<~[~[u8]]>> { + fn get_global_ptr() -> *mut Option<Box<Vec<~[u8]>>> { unsafe { cast::transmute(&global_args_ptr) } } // Copied from `os`. #[cfg(not(test))] - unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~[u8]] { + unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> Vec<~[u8]> { use c_str::CString; use ptr::RawPtr; use libc; @@ -133,7 +135,7 @@ mod imp { Vec::from_fn(argc as uint, |i| { let cs = CString::new(*(argv as **libc::c_char).offset(i as int), false); cs.as_bytes_no_nul().to_owned() - }).move_iter().collect() + }) } #[cfg(test)] @@ -147,7 +149,7 @@ mod imp { // Preserve the actual global state. let saved_value = take(); - let expected = box [bytes!("happy").to_owned(), bytes!("today?").to_owned()]; + let expected = vec![bytes!("happy").to_owned(), bytes!("today?").to_owned()]; put(expected.clone()); assert!(clone() == Some(expected.clone())); @@ -170,6 +172,7 @@ mod imp { #[cfg(target_os = "win32", not(test))] mod imp { use option::Option; + use vec::Vec; pub unsafe fn init(_argc: int, _argv: **u8) { } @@ -177,15 +180,15 @@ mod imp { pub fn cleanup() { } - pub fn take() -> Option<~[~[u8]]> { + pub fn take() -> Option<Vec<~[u8]>> { fail!() } - pub fn put(_args: ~[~[u8]]) { + pub fn put(_args: Vec<~[u8]>) { fail!() } - pub fn clone() -> Option<~[~[u8]]> { + pub fn clone() -> Option<Vec<~[u8]>> { fail!() } } diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index 16882624ab7..ccde8d9c96a 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -161,7 +161,7 @@ pub trait IoFactory { fn unix_connect(&mut self, path: &CString, timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>>; fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>, - hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>; + hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>>; // filesystem operations fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) @@ -191,7 +191,7 @@ pub trait IoFactory { fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>>; fn spawn(&mut self, config: ProcessConfig) -> IoResult<(Box<RtioProcess:Send>, - ~[Option<Box<RtioPipe:Send>>])>; + Vec<Option<Box<RtioPipe:Send>>>)>; fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>; fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>>; fn tty_open(&mut self, fd: c_int, readable: bool) |
