作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个Iterator
实现,如下所示:
struct MyType {
// stuff
}
struct Snapshot {
// stuff
}
impl MyType {
pub fn iter(&mut self) -> MyIterator {
MyIterator {
foo: self
}
}
}
struct MyIterator<'a> {
foo: &'a mut MyType
}
impl<'a> Iterator for MyIterator<'a> {
type Item = Snapshot;
fn next(&mut self) -> Option<Self::Item> {
if self.cheap_condition() {
self.cheap_mutation(); // Inexpensive
let s: Snapshot = self.snapshot(); // Expensive copying
Some(s)
} else {
None
}
}
}
如果我想使用生成的
Snapshot
的每个实例,这都可以很好地工作,但是如果我想使用类似
Iterator::step_by
或
Iterator::last
的东西,而我不在乎中间的
Snapshot
s,则生成这些未使用的值所产生的成本是巨大的性能打击。
Iterator
的每个方法,以便仅在必要时才进行昂贵的操作,但是我觉得必须有一种更简单,更惯用的方式来做到这一点,或者是一种懒惰地生成与
Snapshot
对应的迭代方式如果尚未再次调用
Item
,则为
Iterator::next
的中间类型。
MyType
的引用,因为我希望我确实生成的
Snapshot
具有独立的生存期,例如,使
Iterator::collect()
的结果可以超过
MyType
实例的生命周期。
最佳答案
您不必重写每个Iterator
方法。唯一相关的是nth
,last
,count
,step_by
和skip
。所有其他方法都需要以某种方式检查Self::Item
,因此您无法避免为这些生成Snapshot
。幸运的是,step_by
和skip
在内部使用nth
,因此实际上只剩下nth
,count
和last
,我们必须对其进行覆盖:
use core::marker::PhantomData;
struct Snapshot;
struct MyType<'a> {
item: PhantomData<&'a ()>,
}
impl<'a> MyType<'a> {
fn cheap_condition(&self) -> bool {
todo!()
}
fn cheap_mutation(&mut self) {
todo!()
}
fn snapshot(&self) -> Snapshot {
Snapshot
}
}
impl<'a> Iterator for MyType<'a> {
type Item = Snapshot;
fn next(&mut self) -> Option<Self::Item> {
if self.cheap_condition() {
self.cheap_mutation(); // Inexpensive
Some(self.snapshot()) // Expensive
} else {
None
}
}
// also covers skip & step_by methods
fn nth(&mut self, n: usize) -> Option<Self::Item> {
for _ in 0..n {
if self.cheap_condition() {
self.cheap_mutation();
} else {
return None;
}
}
self.next()
}
fn count(mut self) -> usize
where
Self: Sized,
{
let mut count: usize = 0;
while self.cheap_condition() {
self.cheap_mutation();
count += 1;
}
count
}
fn last(mut self) -> Option<Self::Item>
where
Self: Sized,
{
while self.cheap_condition() {
self.cheap_mutation();
if !self.cheap_condition() {
return Some(self.snapshot());
}
}
None
}
}
playground
Iterator
而不是
filter
的谓词来使诸如
MyType<'a>
的其他
Snapshot
方法变得懒惰,则必须为此定义自己的类似于
Iterator
的特征,因为所有其他方法仅适用于
Self::Item
。
关于rust - 当某些值被忽略时,如何避免迭代器实现中不必要的昂贵操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66141933/
我正在阅读 MongoDB,并试图了解它的最佳用途。我没有看到明确答案的一个问题是哪些操作便宜或昂贵,以及在什么条件下。 你能帮忙澄清一下吗? 谢谢。 最佳答案 人们经常声称 mongodb 的写入速
我正在寻找一个主要来源(或一个非常好的解释)来支持在为 iPhone 编写软件时使用 autorelease 是危险的或过于昂贵的说法。 许多开发者都提出了这种说法,我什至听说 Apple 不推荐它,
我意识到这离微优化领域太远了,但我很想知道为什么调用 DateTime.Now 和 DateTime.UtcNow 如此“昂贵”。我有一个示例程序,它运行几个场景来做一些“工作”(添加到一个计数器)并
我是一名优秀的程序员,十分优秀!