Rust 当某些值被忽略时,如何避免迭代器实现中不必要的昂贵操作?
我有一个Rust 当某些值被忽略时,如何避免迭代器实现中不必要的昂贵操作?,rust,iterator,traits,lazy-evaluation,iterator-traits,Rust,Iterator,Traits,Lazy Evaluation,Iterator Traits,我有一个迭代器实现,如下所示: struct MyType { // stuff } struct Snapshot { // stuff } impl MyType { pub fn iter(&mut self) -> MyIterator { MyIterator { foo: self } } } struct MyIterator<'a> { foo: &am
迭代器
实现,如下所示:
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
}
}
}
struct MyType{
//东西
}
结构快照{
//东西
}
impl MyType{
pub fn iter(&mut self)->MyIterator{
我的迭代器{
福:自我
}
}
}
结构MyIterator{
类型项=快照;
fn下一步(&mut self)->选项{
如果self.cheap_条件(){
self.cheap_mutation();//便宜
设s:Snapshot=self.Snapshot();//昂贵的复制
部分
}否则{
没有一个
}
}
}
如果我想使用生成的快照的每个实例,这很好,但是如果我想使用迭代器::step_by
或迭代器::last
之类的东西,我不关心中间的快照
,那么生成这些未使用的值所产生的成本是一个巨大的性能损失
我可以覆盖迭代器的每一个方法,这样昂贵的操作只在必要时发生,但我觉得必须有一种更简单、更惯用的方法来完成,或者,如果未再次调用迭代器::next
,则可以通过中间类型为项
惰性地生成与迭代相对应的快照
我不想返回对MyType
的引用,因为我希望生成的Snapshot
s具有独立的生存时间,例如,允许Iterator::collect()
的结果比MyType
的实例寿命长,您不必覆盖每个迭代器
方法。唯一相关的是第n个
,最后一个
,计数
,步进
,和跳过
。所有其他方法都需要以某种方式检查Self::Item
,因此无法避免为这些方法生成Snapshot
s。幸运的是,step\u by
和skip
在内部使用nth
,因此我们只剩下nth
、count
和last
,我们必须覆盖:
使用core::marker::PhantomData;
结构快照;
结构MyType,
}
恳求{
fn廉价_条件(自身)->bool{
待办事项!()
}
fn廉价突变(&mut-self){
待办事项!()
}
fn快照(&self)->快照{
快照
}
}
恳求{
类型项=快照;
fn下一步(&mut self)->选项{
如果self.cheap_条件(){
self.cheap_mutation();//便宜
有些(self.snapshot())//价格昂贵
}否则{
没有一个
}
}
//还包括方法的跳过和步骤
fn第n个(&mut self,n:usize)->选项{
对于0..n中的uu{
如果self.cheap_条件(){
self.cheap_突变();
}否则{
不返回任何值;
}
}
self.next()
}
fn计数(多个自身)->使用
哪里
自我:大小,
{
让mut计数:usize=0;
而self.cheap_条件(){
self.cheap_突变();
计数+=1;
}
计数
}
fn最后一个(多个自)->选项
哪里
自我:大小,
{
而self.cheap_条件(){
self.cheap_突变();
if!self.cheap_条件(){
返回一些(self.snapshot());
}
}
没有一个
}
}
如果您想通过检查MyTypeI的谓词使其他Iterator
方法(如filter
)变得懒惰,我可以覆盖Iterator的每个方法,这样昂贵的操作只在必要时发生-我相信这是正确的解决方案。如果是,那么我想没有其他选择,我想我可以添加某种函数来避免重复相同的代码,但我想看看是否有人有更好的想法。谢谢你的编辑。谢谢你的回答!我不确定step_by
等的内部实现,因此感谢您的澄清。我想这是正确的答案,所以我会将其标记为正确答案。另外相关的可能是iter\u advance\u by
功能,尽管它目前(尚未)稳定。last
的实现是错误的:如果迭代器为空,它将到达无法访问的!()
声明@谢谢你的评论,我更新了我的答案。