【发布时间】:2021-09-30 21:58:16
【问题描述】:
我基本上必须浏览一张图片并对其应用不同的过滤器。我使用的基本代码如下所示,我的示例在 ~0.37 秒内运行:
let mut changed = true;
while changed {
changed = false;
// I need to clone here so I dont use the changed data
let past = self.grid.clone();
// My data is in a vector, this gives me all x/y combinations
for (x, y) in GridIndexIter::from(0, self.width as i32, 0, self.height as i32) {
// This gives me the index of the current piece
let i = self.ind(x, y);
let root = past[i];
// Here I apply my filter (if no value, set it to a neighboring value)
if root.elevation == None {
let surround: Option<Tile> = GridIndexIter::from(-1, 2, -1, 2)
.map(|(x_add, y_add)| past[self.ind(x + x_add, y + y_add)])
.filter(|tile| tile.elevation != None)
.nth(0);
if let Some(tile) = surround {
self.grid[i].elevation = tile.elevation;
changed = true;
}
}
}
}
但是因为我想运行多个过滤器,所有这些过滤器都以相同的方式应用但在实际计算中有所不同(我可能想要平滑值等等),我尝试将其拆分为应用的基本逻辑一个过滤器和该过滤器的逻辑,我将其设置为闭包,但现在我的示例需要大约 4.5 秒:
fn apply_filter(&mut self, condition: fn(Tile) -> bool, filter: fn(Vec<Tile>) -> Option<Tile>) {
let mut changed = true;
while changed {
changed = false;
let past = self.grid.clone();
for (x, y) in GridIndexIter::from(0, self.width as i32, 0, self.height as i32) {
let i = self.ind(x, y);
let root = past[i];
if condition(root) {
if let Some(tile) = filter(GridIndexIter::from(-1, 2, -1, 2)
.map(|(x_add, y_add)| past[self.ind(x + x_add, y + y_add)])
.collect()) {
self.grid[i].elevation = tile.elevation;
changed = true;
}
}
}
}
}
self.apply_filter(|tile| tile.elevation == None,
|past| {
if let Some(tile) = past.iter().filter(|tile| tile.elevation != None).nth(0) {
return Some(Tile {
elevation: tile.elevation,
..past[4]
});
} None
}
);
我做错了吗?有没有办法让关闭更有效率?有没有其他方法可以达到同样的效果?
【问题讨论】:
-
您是否正在使用
--release构建/运行? -
您在后面的示例中将
GridIndexIter收集到Vec中,但在另一个示例中没有。为什么不让filter函数直接使用impl Iterator或GridIndexIter? -
是的,我在这两种情况下都在构建版本。我可以使用一个迭代器,它会更好一些,我会改变它,但这不应该产生如此巨大的差异,对吧?
-
应该的,因为每一个
.collect放到一个vector中就是一个堆内存的分配,分配几次也不错,但是你为每个像素分配一个 -
您能否提供一个最小且可运行的代码版本,以供其他人用来进行基准测试?没有它,就很难为这个问题提供权威的答案。
标签: performance rust closures