I have another question regarding this code:
This is one version (here just the main function):
fn main() {
use std::fs::File;
use std::io::Read;
let mut data = String::new();
File::open("points.json").unwrap().read_to_string(&mut data).unwrap();
let points = data
.trim_matches(&['[', ']'][..])
.split("],[")
.map(|r| r.split(",").map(|p| p.parse().unwrap()))
.map(|mut r| V2(r.next().unwrap(), r.next().unwrap()))
.collect::<Vec<V2>>();
let iterations = 300;
println!("The average time is {:.1} ms.", benchmark(&points, iterations) * 1000.0);
}
And this is modified code:
fn load_data(file_name: &str) -> Vec<V2> {
use std::fs::File;
use std::io::Read;
let mut data = String::new();
File::open(file_name).unwrap().read_to_string(&mut data).unwrap();
data
.trim_matches(&['[', ']'][..])
.split("],[")
.map(|r| r.split(",").map(|p| p.parse().unwrap()))
.map(|mut r| V2(r.next().unwrap(), r.next().unwrap()))
.collect::<Vec<V2>>()
}
fn main() {
let points = load_data("points.json");
let iterations = 300;
println!("The average time is {:.1} ms.", benchmark(&points, iterations) * 1000.0);
}
I've seen that the original version runs using about 9 MB RAM, while the modified takes about 5 MB. This is interesting. I guess the cause is that in the first version the data
string is kept in memory until the end of the program, while in the second program it's deallocated when load_data
ends (the string is about 3.8 MB).
The situation in a simpler example:
fn main() {
let v1 = vec![10, 20, 30];
let x = v1[1];
let mut v2 = vec![1, 2, 3, 4];
v2[1] = x;
}
I guess currently v1 is kept allocated until the end of main(), but the vector v1 is never referenced past the assignment of x, and the Rust compiler tracks the lifetimes of all variables. So why isn't Rust deallocating v1 after the creation of x?