Library vecs are fast now.

This commit is contained in:
Eric Holk 2012-06-14 11:38:45 -07:00
parent 0e5cfd9f33
commit 9bdb2c9e48
6 changed files with 40 additions and 16 deletions

View File

@ -113,6 +113,7 @@ impl extensions<A> for dvec<A> {
and return a new vector to replace it with.
"]
#[inline(always)]
fn swap(f: fn(-[mut A]) -> [mut A]) {
self.borrow { |v| self.return(f(v)) }
}
@ -136,11 +137,8 @@ impl extensions<A> for dvec<A> {
impl extensions<A:copy> for dvec<A> {
#[doc = "Append a single item to the end of the list"]
fn push(t: A) {
self.swap { |v|
let mut v <- v;
vec::push(v, t);
v
}
self.check_not_borrowed();
vec::push(self.data, t);
}
#[doc = "Remove and return the last element"]

View File

@ -51,6 +51,7 @@ pure fn get_type_desc<T>() -> *type_desc {
}
#[doc = "Returns the size of a type"]
#[inline(always)]
pure fn size_of<T>() -> uint unsafe {
unchecked { rusti::size_of::<T>() }
}

View File

@ -81,6 +81,7 @@ fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
}
#[doc = "Returns the smallest power of 2 greater than or equal to `n`"]
#[inline(always)]
fn next_power_of_two(n: uint) -> uint {
let halfbits: uint = sys::size_of::<uint>() * 4u;
let mut tmp: uint = n - 1u;

View File

@ -92,6 +92,11 @@ native mod rustrt {
++count: libc::size_t) -> *unsafe::vec_repr;
}
#[abi = "rust-intrinsic"]
native mod rusti {
fn move_val_init<T>(&dst: T, -src: T);
}
#[doc = "A function used to initialize the elements of a vector"]
type init_op<T> = fn(uint) -> T;
@ -392,17 +397,33 @@ fn pop<T>(&v: [const T]) -> T unsafe {
#[doc = "Append an element to a vector"]
#[inline(always)]
fn push<T>(&v: [const T], +initval: T) {
let ln = v.len();
unsafe {
reserve_at_least(v, ln + 1u);
unsafe::set_len(v, ln + 1u);
let p = ptr::mut_addr_of(v[ln]);
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
let fill = (**repr).fill;
if (**repr).alloc > fill {
let sz = sys::size_of::<T>();
(**repr).fill += sz;
let p = ptr::addr_of((**repr).data);
let p = ptr::offset(p, fill) as *mut T;
rusti::move_val_init(*p, initval);
}
else {
push_slow(v, initval);
}
}
}
// FIXME: for performance, try replacing the memmove and <- with a
// memset and unsafe::forget.
ptr::memset(p, 0, 1u); // needed to stop drop glue from running on
// garbage data.
*p = initval;
fn push_slow<T>(&v: [const T], +initval: T) {
unsafe {
let ln = v.len();
reserve_at_least(v, ln + 1u);
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
let fill = (**repr).fill;
let sz = sys::size_of::<T>();
(**repr).fill += sz;
let p = ptr::addr_of((**repr).data);
let p = ptr::offset(p, fill) as *mut T;
rusti::move_val_init(*p, initval);
}
}
@ -497,6 +518,7 @@ Sets the element at position `index` to `val`. If `index` is past the end
of the vector, expands the vector by replicating `initval` to fill the
intervening space.
"]
#[inline(always)]
fn grow_set<T: copy>(&v: [mut T], index: uint, initval: T, val: T) {
if index >= len(v) { grow(v, index - len(v) + 1u, initval); }
v[index] = val;

View File

@ -19,6 +19,7 @@ fn mk<T: copy>() -> smallintmap<T> {
Add a value to the map. If the map already contains a value for
the specified key then the original value is replaced.
"]
#[inline(always)]
fn insert<T: copy>(self: smallintmap<T>, key: uint, val: T) {
self.v.grow_set_elt(key, none, some(val));
}
@ -62,6 +63,7 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
}
sz
}
#[inline(always)]
fn insert(+key: uint, +value: V) -> bool {
let exists = contains_key(self, key);
insert(self, key, value);

View File

@ -7,8 +7,8 @@ import io::writer_util;
fn collect_raw(num: uint) -> [uint] {
let mut result = [];
for uint::range(0u, num) { |i|
result += [i];
//vec::push(result, i);
//result += [i];
vec::push(result, i);
//result = vec::append(result, [i]);
}
ret result;