提问人:Shane 提问时间:7/8/2023 最后编辑:Shane 更新时间:7/8/2023 访问量:68
尽管使用了引用,但函数使用过多的内存
Function using too much memory despite using references
问:
我有一个函数(准确的方法),其主要目的是压缩多个向量(类似于 Python 中的函数)。zip
变量的两个向量都非常大,但考虑到这些是引用向量,我相信内存使用不会成为问题。我错了,此代码经常遇到内存分配问题并由于内存不足而崩溃。windows
当代码立即命中受存储 IO 限制的分页内存时,任何性能改进都会被抹去。
我尝试了代码的几种变体,但它们似乎都遇到了同样的问题。
在我的理解中,唯一的大内存分配发生在创建变量时(发生在不同的方法中)。完成初始分配后,该方法中不应发生额外的大型分配,因为它仅处理对原始数据的引用。这是正确的理解吗?windows
create_zipped_kmers
我在代码中是否做错了什么,或者我的知识存在差距?如何在保持性能的同时减少内存使用量?
变体 1
fn create_zipped_kmers(&'a self, windows: &'a Vec<Vec<&'a str>>) -> Vec<Vec<&'a str>> {
if windows.is_empty() {
panic!("Sequence k-mer vector cannot be empty");
}
let num_cols = windows.iter().map(|v| v.len()).min().unwrap_or(0);
let num_rows = windows.len();
let mut zipped = Vec::with_capacity(num_cols);
for col_index in 0..num_cols {
let column: Vec<&str> = (0..num_rows)
.into_par_iter()
.map(|row_index| windows[row_index][col_index])
.collect();
zipped.push(column);
}
zipped
}
变体 2
fn create_zipped_kmers(&'a self, windows: &'a Vec<Vec<&'a str>>) -> Vec<Vec<&'a str>> {
if windows.is_empty() {
panic!("Sequence k-mer vector cannot be empty");
}
let num_cols = windows.iter().map(|v| v.len()).min().unwrap_or(0);
let num_rows = windows.len();
(0..num_cols)
.into_par_iter()
.map(|col_index| {
(0..num_rows)
.map(|row_index| windows[row_index][col_index])
.collect::<Vec<&str>>()
})
.collect()
}
变体 3
fn create_zipped_kmers(&'a self, windows: &'a Vec<Vec<&'a str>>) -> Vec<Vec<&'a str>> {
if windows.is_empty() {
panic!("Sequence k-mer vector cannot be empty");
}
let num_seqs = windows[0].len();
let mut iters: Vec<_> = windows.par_iter().map(|n| n.into_iter()).collect();
(0..num_seqs)
.map(|_| {
iters
.par_iter_mut()
.map(|n| *n.next().unwrap())
.collect()
})
.collect()
}
谢谢。
答: 暂无答案
评论
windows
.into_par_iter()
vec.capacity() * size of each element
.len()