Two dimensional vectors in Rust - vector

Editor's note: This question predates Rust 0.1 (tagged 2013-07-03) and is not syntactically valid Rust 1.0 code. Answers may still contain valuable information.
Does anyone know how to create mutable two-dimensional vectors in Rust and pass them to a function to be manipulated?
This is what I tried so far:
extern crate std;
fn promeni(rec: &[u8]) {
rec[0][1] = 0x01u8;
}
fn main() {
let mut rec = ~[[0x00u8,0x00u8],
[0x00u8,0x00u8]
];
io::println(u8::str(rec[0][1]));
promeni(rec);
io::println(u8::str(rec[0][1]));
}

You could use the macro vec! to create 2d vectors.
fn test(vec: &mut Vec<Vec<char>>){
vec[0][0] = 'd';
..//
vec[23][79] = 'd';
}
fn main() {
let mut vec = vec![vec!['#'; 80]; 24];
test(&mut vec);
}

Did you intend that all of the subarrays will have the length 2, as in this example? In that case, the type of the parameter should not be &[u8], which is a borrowed array of u8's, but rather &[[u8; 2]].

If the functions that is going to manipulate are yours, you can create a custom struct with the helper methods to treat the vector as 2d:
use std::fmt;
#[derive(Debug)]
pub struct Vec2d<T> {
vec: Vec<T>,
row: usize,
col: usize,
}
impl<T> Vec2d<T> {
pub fn new(vec: Vec<T>, row: usize, col: usize) -> Self {
assert!(vec.len() == row * col);
Self { vec, row, col }
}
pub fn row(&self, row: usize) -> &[T] {
let i = self.col * row;
&self.vec[i..(i + self.col)]
}
pub fn index(&self, row: usize, col: usize) -> &T {
let i = self.col * row;
&self.vec[i + col]
}
pub fn index_mut(&mut self, row: usize, col: usize) -> &mut T {
let i = self.col * row;
&mut self.vec[i + col]
}
}
impl<T: std::fmt::Debug> std::fmt::Display for Vec2d<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut str = String::new();
for i in 0..self.row {
if i != 0 {
str.push_str(", ");
}
str.push_str(&format!("{:?}", &self.row(i)));
}
write!(f, "[{}]", str)
}
}
fn main() {
let mut mv = Vec2d::new(vec![1, 2, 3, 4, 5, 6], 2, 3);
*mv.index_mut(1, 2) = 10;
println!("Display: {}", mv);
println!("Debug: {:?}", mv);
}
The associated function new creates the Vec2d, have two main methods (index and index_mut, so you can get a index value borrowed immut ou mut) and added a Display trait to visualise it better (but it is stored as Vec<>).

Related

How can I hold a boxed async function that captures variables?

I want to have a boxed async function from a closure that can capture variables:
use std::future::Future;
use std::pin::Pin;
fn constrain<Fun>(fun: Fun) -> Fun
where
Fun: for<'arg> Fn(&'arg usize, &'arg usize) -> Pin<Box<dyn Future<Output = usize> + 'arg>>,
{
fun
}
struct Test {}
impl Test {
pub async fn fun<'test, 'arg>(&'test self, val0: &'arg usize, val1: &'arg usize) -> usize
where
'arg: 'test,
{
*val0 + *val1
}
}
pub async fn fun<'arg>(val0: &'arg usize, val1: &'arg usize) -> usize {
val0 + val1
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
let test = Test {};
let boxed = Box::new(constrain(move |v0, v1| {
let ret = Box::pin(async {
test.fun(v0, v1).await
//fun(v0, v1).await
});
ret
}));
let v0 = 10;
let v1 = 20;
let ret = boxed(&v0, &v1).await;
println!("{ret}");
}
When I call 'fun', it works, because it doesn't capture 'test'. When I call 'test.fun(...)', it fails:
error: lifetime may not live long enough
--> src/main.rs:46:9
|
38 | let boxed = Box::new(constrain(move |v0, v1|
| -------------
| | |
| | has type `&'2 usize`
| lifetime `'1` represents this closure's body
...
46 | ret
| ^^^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
error: could not compile `playground` due to previous error
I don't know how to constrain the closure's lifetime to the arguments.
Here's something that gets close:
use std::pin::Pin;
use std::future::Future;
#[macro_use]
extern crate derive_new;
#[derive(new)]
struct Test
{
}
impl Test
{
pub async fn fun<'test, 'arg>(&'test self, val0: &'arg usize, val1: &'arg usize) -> usize
where 'arg: 'test
{
*val0 + *val1
}
}
trait ClosureFn
{
fn call<'myself, 'arg>(&'myself self, v0: &'arg usize, v1: &'arg usize) -> Pin<Box<dyn Future<Output = usize> + 'myself>>
where 'arg: 'myself;
}
#[derive(new)]
struct Closure
{
test: Test
}
impl ClosureFn for Closure
{
fn call<'myself, 'arg>(&'myself self, v0: &'arg usize, v1: &'arg usize) -> Pin<Box<dyn Future<Output = usize> + 'myself>>
where 'arg: 'myself
{
Box::pin(async
{
self.test.fun(v0, v1).await
})
}
}
#[tokio::main(flavor = "current_thread")]
async fn main()
{
let test = Test::new();
let boxed: Box<dyn ClosureFn> = Box::new(Closure::new(test));
let v0 = 10;
let v1 = 20;
let ret = boxed.call(&v0, &v1).await;
println!("{ret}");
}
Unfortunatelly, you need to create the 'Closure' structure, and call the function via 'call'.
I was missing a move at the async function, I got confused by the compiler's error message:
use std::future::Future;
use std::pin::Pin;
fn constrain<Fun>(fun: Fun) -> Fun
where
Fun: for<'arg> Fn(&'arg usize, &'arg usize) -> Pin<Box<dyn Future<Output = usize> + 'arg>>,
{
fun
}
#[derive(Clone)]
struct Test {}
impl Test
{
pub async fn fun<'test, 'arg>(&'test self, val0: &'arg usize, val1: &'arg usize) -> usize
where
'arg: 'test,
{
*val0 + *val1
}
}
pub async fn fun<'arg>(val0: &'arg usize, val1: &'arg usize) -> usize {
val0 + val1
}
#[tokio::main(flavor = "current_thread")]
async fn main()
{
let test = Test{};
let boxed = Box::new(constrain(move |v0, v1|
{
let test = test.clone();
let ret = Box::pin(async move
{
test.fun(v0, v1).await
//fun(v0, v1).await
});
ret
}));
let v0 = 10;
let v1 = 20;
let ret = boxed(&v0, &v1).await;
println!("{ret}");
}
I found the solution here, it happened to someone else too:
https://users.rust-lang.org/t/lifetimes-issue-while-storing-rust-async-closure-functions-for-later-invocation/52232/2

How to bulk insert into a vector in rust? [duplicate]

Is there any straightforward way to insert or replace multiple elements from &[T] and/or Vec<T> in the middle or at the beginning of a Vec in linear time?
I could only find std::vec::Vec::insert, but that's only for inserting a single element in O(n) time, so I obviously cannot call that in a loop.
I could do a split_off at that index, extend the new elements into the left half of the split, and then extend the second half into the first, but is there a better way?
As of Rust 1.21.0, Vec::splice is available and allows inserting at any point, including fully prepending:
let mut vec = vec![1, 5];
let slice = &[2, 3, 4];
vec.splice(1..1, slice.iter().cloned());
println!("{:?}", vec); // [1, 2, 3, 4, 5]
The docs state:
Note 4: This is optimal if:
The tail (elements in the vector after range) is empty
or replace_with yields fewer elements than range’s length
or the lower bound of its size_hint() is exact.
In this case, the lower bound of the slice's iterator should be exact, so it should perform one memory move.
splice is a bit more powerful in that it allows you to remove a range of values (the first argument), insert new values (the second argument), and optionally get the old values (the result of the call).
Replacing a set of items
let mut vec = vec![0, 1, 5];
let slice = &[2, 3, 4];
vec.splice(..2, slice.iter().cloned());
println!("{:?}", vec); // [2, 3, 4, 5]
Getting the previous values
let mut vec = vec![0, 1, 2, 3, 4];
let slice = &[9, 8, 7];
let old: Vec<_> = vec.splice(3.., slice.iter().cloned()).collect();
println!("{:?}", vec); // [0, 1, 2, 9, 8, 7]
println!("{:?}", old); // [3, 4]
Okay, there is no appropriate method in Vec interface (as I can see). But we can always implement the same thing ourselves.
memmove
When T is Copy, probably the most obvious way is to move the memory, like this:
fn push_all_at<T>(v: &mut Vec<T>, offset: usize, s: &[T]) where T: Copy {
match (v.len(), s.len()) {
(_, 0) => (),
(current_len, _) => {
v.reserve_exact(s.len());
unsafe {
v.set_len(current_len + s.len());
let to_move = current_len - offset;
let src = v.as_mut_ptr().offset(offset as isize);
if to_move > 0 {
let dst = src.offset(s.len() as isize);
std::ptr::copy_memory(dst, src, to_move);
}
std::ptr::copy_nonoverlapping_memory(src, s.as_ptr(), s.len());
}
},
}
}
shuffle
If T is not copy, but it implements Clone, we can append given slice to the end of the Vec, and move it to the required position using swaps in linear time:
fn push_all_at<T>(v: &mut Vec<T>, mut offset: usize, s: &[T]) where T: Clone + Default {
match (v.len(), s.len()) {
(_, 0) => (),
(0, _) => { v.push_all(s); },
(_, _) => {
assert!(offset <= v.len());
let pad = s.len() - ((v.len() - offset) % s.len());
v.extend(repeat(Default::default()).take(pad));
v.push_all(s);
let total = v.len();
while total - offset >= s.len() {
for i in 0 .. s.len() { v.swap(offset + i, total - s.len() + i); }
offset += s.len();
}
v.truncate(total - pad);
},
}
}
iterators concat
Maybe the best choice will be to not modify Vec at all. For example, if you are going to access the result via iterator, we can just build iterators chain from our chunks:
let v: &[usize] = &[0, 1, 2];
let s: &[usize] = &[3, 4, 5, 6];
let offset = 2;
let chain = v.iter().take(offset).chain(s.iter()).chain(v.iter().skip(offset));
let result: Vec<_> = chain.collect();
println!("Result: {:?}", result);
I was trying to prepend to a vector in rust and found this closed question that was linked here, (despite this question being both prepend and insert AND efficiency. I think my answer would be better as an answer for that other, more precises question because I can't attest to the efficiency), but the following code helped me prepend, (and the opposite.) [I'm sure that the other two answers are more efficient, but the way that I learn, I like having answers that can be cut-n-pasted with examples that demonstrate an application of the answer.]
pub trait Unshift<T> { fn unshift(&mut self, s: &[T]) -> (); }
pub trait UnshiftVec<T> { fn unshift_vec(&mut self, s: Vec<T>) -> (); }
pub trait UnshiftMemoryHog<T> { fn unshift_memory_hog(&mut self, s: Vec<T>) -> (); }
pub trait Shift<T> { fn shift(&mut self) -> (); }
pub trait ShiftN<T> { fn shift_n(&mut self, s: usize) -> (); }
impl<T: std::clone::Clone> ShiftN<T> for Vec<T> {
fn shift_n(&mut self, s: usize) -> ()
// where
// T: std::clone::Clone,
{
self.drain(0..s);
}
}
impl<T: std::clone::Clone> Shift<T> for Vec<T> {
fn shift(&mut self) -> ()
// where
// T: std::clone::Clone,
{
self.drain(0..1);
}
}
impl<T: std::clone::Clone> Unshift<T> for Vec<T> {
fn unshift(&mut self, s: &[T]) -> ()
// where
// T: std::clone::Clone,
{
self.splice(0..0, s.to_vec());
}
}
impl<T: std::clone::Clone> UnshiftVec<T> for Vec<T> {
fn unshift_vec(&mut self, s: Vec<T>) -> ()
where
T: std::clone::Clone,
{
self.splice(0..0, s);
}
}
impl<T: std::clone::Clone> UnshiftMemoryHog<T> for Vec<T> {
fn unshift_memory_hog(&mut self, s: Vec<T>) -> ()
where
T: std::clone::Clone,
{
let mut tmp: Vec<_> = s.to_owned();
//let mut tmp: Vec<_> = s.clone(); // this also works for some data types
/*
let local_s: Vec<_> = self.clone(); // explicit clone()
tmp.extend(local_s); // to vec is possible
*/
tmp.extend(self.clone());
*self = tmp;
//*self = (*tmp).to_vec(); // Just because it compiles, doesn't make it right.
}
}
// this works for: v = unshift(v, &vec![8]);
// (If you don't want to impl Unshift for Vec<T>)
#[allow(dead_code)]
fn unshift_fn<T>(v: Vec<T>, s: &[T]) -> Vec<T>
where
T: Clone,
{
// create a mutable vec and fill it
// with a clone of the array that we want
// at the start of the vec.
let mut tmp: Vec<_> = s.to_owned();
// then we add the existing vector to the end
// of the temporary vector.
tmp.extend(v);
// return the tmp vec that is identitcal
// to unshift-ing the original vec.
tmp
}
/*
N.B. It is sometimes (often?) more memory efficient to reverse
the vector and use push/pop, rather than splice/drain;
Especially if you create your vectors in "stack order" to begin with.
*/
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3];
println!("Before push:\t {:?}", v);
v.push(0);
println!("After push:\t {:?}", v);
v.pop();
println!("popped:\t\t {:?}", v);
v.drain(0..1);
println!("drain(0..1)\t {:?}", v);
/*
// We could use a function
let c = v.clone();
v = unshift_fn(c, &vec![0]);
*/
v.splice(0..0, vec![0]);
println!("splice(0..0, vec![0]) {:?}", v);
v.shift_n(1);
println!("shift\t\t {:?}", v);
v.unshift_memory_hog(vec![8, 16, 31, 1]);
println!("MEMORY guzzler unshift {:?}", v);
//v.drain(0..3);
v.drain(0..=2);
println!("back to the start: {:?}", v);
v.unshift_vec(vec![0]);
println!("zerothed with unshift: {:?}", v);
let mut w = vec![4, 5, 6];
/*
let prepend_this = &[1, 2, 3];
w.unshift_vec(prepend_this.to_vec());
*/
w.unshift(&[1, 2, 3]);
assert_eq!(&w, &[1, 2, 3, 4, 5, 6]);
println!("{:?} == {:?}", &w, &[1, 2, 3, 4, 5, 6]);
}

Borrow error when attempting recursion on HashMap, where each value needs a reference to the map

I'm currently have an issue regarding Rust's borrowing policy.
I have a HashMap of structs 'Value', each which contains a list of keys to other Values in HashMap. I am attempting to recursively call a function on these Values which requires a reference to the HashMap.
use std::collections::HashMap;
struct Value {
val: f64,
prevs: Vec<usize>,
sum: f64,
}
impl Value {
pub fn new(i: usize) -> Value {
let mut res = Value {
val: 0.1,
prevs: Vec::new(),
sum: 0.0,
};
for j in 0..i {
res.prevs.push(j);
}
res
}
pub fn evaluate(&mut self, pool: &mut HashMap<usize, Value>) -> f64 {
self.sum = self.val;
for i in &self.prevs {
let prev = pool.get_mut(i).unwrap();
self.sum += prev.evaluate(pool);
}
self.sum
}
}
fn main() {
let mut hm: HashMap<usize, Value> = HashMap::new();
for i in 0..10 {
hm.insert(i, Value::new(i));
}
println!("{}", hm.get(&9).unwrap().evaluate(&mut hm));
}
Error:
error[E0499]: cannot borrow `*pool` as mutable more than once at a time
--> src/lib.rs:25:39
|
24 | let prev = pool.get_mut(i).unwrap();
| --------------- first mutable borrow occurs here
25 | self.sum += prev.evaluate(pool);
| -------- ^^^^ second mutable borrow occurs here
| |
| first borrow later used by call
Playground
Context
I'm attempting to calculate the output of a neural network (usually done via feedforward) by starting from the output, and recursively evaluating each node, as a weighted sum of the nodes connected to it, with an unpredictable topology. This requires each node having a list of input_nodes, which are keys to a node pool HashMap.
Below is a sample with a few variants:
Non-performant and probably deadlock-prone but compiling version using Arc<Mutex>
High-performance version using Vec and split_at_mut
Highly unsafe, UB and "against-all-good-practices" version using Vec and pointers. At least evaluates to the same number, wanted to add for performance comparison.
#![feature(test)]
extern crate test;
use std::{collections::HashMap, sync::{Arc, Mutex}};
#[derive(Debug)]
struct Value {
val: f64,
prevs: Vec<usize>,
sum: f64,
}
impl Value {
pub fn new(i: usize) -> Value {
let mut res = Value {
val: 0.1,
prevs: Vec::new(),
sum: 0.0,
};
for j in 0..i {
res.prevs.push(j);
}
res
}
pub fn evaluate(&mut self, pool: &mut HashMap<usize, Arc<Mutex<Value>>>) -> f64 {
self.sum = self.val;
for i in &self.prevs {
let val = pool.get_mut(i).unwrap().clone();
self.sum += val.lock().unwrap().evaluate(pool);
}
self.sum
}
pub fn evaluate_split(&mut self, pool: &mut [Value]) -> f64 {
self.sum = self.val;
for i in &self.prevs {
let (hm, val) = pool.split_at_mut(*i);
self.sum += val[0].evaluate_split(hm);
}
self.sum
}
// OBS! Don't do this, horribly unsafe and wrong
pub unsafe fn evaluate_unsafe(&mut self, pool: *const Value, pool_len: usize) -> f64 {
let pool = std::slice::from_raw_parts_mut(pool as *mut Value, pool_len);
self.sum = self.val;
for i in &self.prevs {
let (pool_ptr, pool_len) = (pool.as_ptr(), pool.len());
self.sum += pool[*i].evaluate_unsafe(pool_ptr, pool_len);
}
self.sum
}
}
fn main() {
// arcmutex
let mut hm: HashMap<usize, Arc<Mutex<Value>>> = HashMap::new();
for i in 0..10 {
hm.insert(i, Arc::new(Mutex::new(Value::new(i))));
}
let val = hm.get(&9).unwrap().clone();
assert_eq!(val.lock().unwrap().evaluate(&mut hm), 51.2);
// split vec
let mut hm = (0..10).map(|v| {
Value::new(v)
}).collect::<Vec<_>>();
let (hm, val) = hm.split_at_mut(9);
assert_eq!((hm.len(), val.len()), (9, 1));
assert_eq!(val[0].evaluate_split(hm), 51.2);
}
#[cfg(test)]
mod tests {
use test::bench;
use super::*;
#[bench]
fn bench_arc_mutex(b: &mut bench::Bencher) {
let mut hm: HashMap<usize, Arc<Mutex<Value>>> = HashMap::new();
for i in 0..10 {
hm.insert(i, Arc::new(Mutex::new(Value::new(i))));
}
b.iter(|| {
let val = hm.get(&9).unwrap().clone();
assert_eq!(val.lock().unwrap().evaluate(&mut hm), 51.2);
});
}
#[bench]
fn bench_split(b: &mut bench::Bencher) {
let mut hm = (0..10).map(|v| {
Value::new(v)
}).collect::<Vec<_>>();
b.iter(|| {
let (hm, val) = hm.split_at_mut(9);
assert_eq!(val[0].evaluate_split(hm), 51.2);
});
}
#[bench]
fn bench_unsafe(b: &mut bench::Bencher) {
let mut hm = (0..10).map(|v| {
Value::new(v)
}).collect::<Vec<_>>();
b.iter(|| {
// OBS! Don't do this, horribly unsafe and wrong
let (hm_ptr, hm_len) = (hm.as_ptr(), hm.len());
let val = &mut hm[9];
assert_eq!(unsafe { val.evaluate_unsafe(hm_ptr, hm_len) }, 51.2);
});
}
}
cargo bench results to:
running 3 tests
test tests::bench_arc_mutex ... bench: 13,249 ns/iter (+/- 367)
test tests::bench_split ... bench: 1,974 ns/iter (+/- 70)
test tests::bench_unsafe ... bench: 1,989 ns/iter (+/- 62)
Also, have a look at https://rust-unofficial.github.io/too-many-lists/index.html

What is the correct pattern for a vector of structs where each struct contains a subset of an array of structs?

I've got code very similar to the following (my filter function is more complex though):
struct MyStruct {
a: i32,
b: i32,
count: i32,
}
impl MyStruct {
fn filter(&self) -> bool {
return self.a > self.b + self.count;
}
}
struct ContainerStruct<'a> {
x: i32,
v: Vec<&'a MyStruct>,
}
fn main() {
let mut list_of_items = vec![
MyStruct {
a: 1,
b: 2,
count: 0,
},
MyStruct {
a: 2,
b: 1,
count: 0,
},
MyStruct {
a: 5,
b: 2,
count: 0,
},
];
let mut count = 0;
let mut list_of_containers: Vec<ContainerStruct> = Vec::new();
while count < 10 {
let mut c = ContainerStruct {
x: 1,
v: Vec::new(),
};
for i in list_of_items.iter_mut() {
i.count = count;
if i.filter() {
c.v.push(i);
}
}
count += 1;
list_of_containers.push(c)
}
}
Which does not compile, due to the following error:
error[E0499]: cannot borrow `list_of_items` as mutable more than once at a time
--> src/main.rs:43:18
|
43 | for i in list_of_items.iter_mut() {
| ^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
I know this is a borrow-checking issue, and I can see the potential problems with references etc. What I don't know is the correct pattern to use to achieve what I'm looking for, which is essentially a vector of structs, where each struct contains a subset of an array of structs.
I need to be able to mutate the structs, so I'm forced into using iter_mut().
However that moves the vector into that scope which then gets released next time I go through the external while loop.
Is there any way to force the vector to live long enough to complete the outer loop? I thought about copying the structs but I don't want to do that. I only need references to each one and copying would introduce an unacceptable overhead due to the size of the vector in question.
This compiles:
use std::cell::Cell;
struct MyStruct {
a: i32,
b: i32,
count: Cell<i32>,
}
impl MyStruct {
fn filter(&self) -> bool {
return self.a > self.b + self.count.get();
}
}
struct ContainerStruct<'a> {
x: i32,
v: Vec<&'a MyStruct>,
}
fn main() {
let mut list_of_items = vec![
MyStruct {
a: 1,
b: 2,
count: Cell::new(0),
},
MyStruct {
a: 2,
b: 1,
count: Cell::new(0),
},
MyStruct {
a: 5,
b: 2,
count: Cell::new(0),
},
];
let mut count = 0;
let mut list_of_containers: Vec<ContainerStruct> = Vec::new();
while count < 10 {
let mut c = ContainerStruct {
x: 1,
v: Vec::new(),
};
for i in list_of_items.iter() {
i.count.set(count);
if i.filter() {
c.v.push(i);
}
}
count += 1;
list_of_containers.push(c)
}
}

Most efficient way to fill a vector from back to front

I am trying to populate a vector with a sequence of values. In order to calculate the first value I need to calculate the second value, which depends on the third value etc etc.
let mut bxs = Vec::with_capacity(n);
for x in info {
let b = match bxs.last() {
Some(bx) => union(&bx, &x.bbox),
None => x.bbox.clone(),
};
bxs.push(b);
}
bxs.reverse();
Currently I just fill the vector front to back using v.push(x) and then reverse the vector using v.reverse(). Is there a way to do this in a single pass?
Is there a way to do this in a single pass?
If you don't mind adapting the vector, it's relatively easy.
struct RevVec<T> {
data: Vec<T>,
}
impl<T> RevVec<T> {
fn push_front(&mut self, t: T) { self.data.push(t); }
}
impl<T> Index<usize> for RevVec<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
&self.data[self.len() - index - 1]
}
}
impl<T> IndexMut<usize> for RevVec<T> {
fn index_mut(&mut self, index: usize) -> &mut T {
let len = self.len();
&mut self.data[len - index - 1]
}
}
The solution using unsafe is below. The unsafe version is slightly more than 2x as fast as the safe version using reverse(). The idea is to use Vec::with_capacity(usize) to allocate the vector, then use ptr::write(dst: *mut T, src: T) to write the elements into the vector back to front. offset(self, count: isize) -> *const T is used to calculate the offset into the vector.
extern crate time;
use std::fmt::Debug;
use std::ptr;
use time::PreciseTime;
fn scanl<T, F>(u : &Vec<T>, f : F) -> Vec<T>
where T : Clone,
F : Fn(&T, &T) -> T {
let mut v = Vec::with_capacity(u.len());
for x in u.iter().rev() {
let b = match v.last() {
None => (*x).clone(),
Some(y) => f(x, &y),
};
v.push(b);
}
v.reverse();
return v;
}
fn unsafe_scanl<T, F>(u : &Vec<T> , f : F) -> Vec<T>
where T : Clone + Debug,
F : Fn(&T, &T) -> T {
unsafe {
let mut v : Vec<T> = Vec::with_capacity(u.len());
let cap = v.capacity();
let p = v.as_mut_ptr();
match u.last() {
None => return v,
Some(x) => ptr::write(p.offset((u.len()-1) as isize), x.clone()),
};
for i in (0..u.len()-1).rev() {
ptr::write(p.offset(i as isize), f(v.get_unchecked(i+1), u.get_unchecked(i)));
}
Vec::set_len(&mut v, cap);
return v;
}
}
pub fn bench_scanl() {
let lo : u64 = 0;
let hi : u64 = 1000000;
let v : Vec<u64> = (lo..hi).collect();
let start = PreciseTime::now();
let u = scanl(&v, |x, y| x + y);
let end= PreciseTime::now();
println!("{:?}\n in {}", u.len(), start.to(end));
let start2 = PreciseTime::now();
let u = unsafe_scanl(&v, |x, y| x + y);
let end2 = PreciseTime::now();
println!("2){:?}\n in {}", u.len(), start2.to(end2));
}

Resources