什么是通过反向迭代器遍历的最快方法

问题描述 投票:7回答:2

比方说,我想通过反向一个通用的迭代迭代,在不知道迭代器的内部,并通过非类型化的魔法本质上不是作弊,并假设这可能是任何类型的迭代中,供应迭代器;我们可以优化迭代器的反向运行时,甚至通过宏?

前锋

var a = [1, 2, 3, 4].iterator();
// Actual iteration bellow
for(i in a) {
   trace(i);
}

向后

var a = [1, 2, 3, 4].iterator();
// Actual reverse iteration bellow
var s = [];
for(i in a) {
    s.push(i);    
}
s.reverse();
for(i in s) {
    trace(i);    
}

我认为必须有一个更简单的方法,或者至少这样的快速的方法。我们无法知道大小,因为迭代器类不携带一个,所以我们不能颠倒到临时数组的推动。但是因为我们知道临时数组的大小,我们可以删除相反。

var a = [1,2,3,4].iterator();
// Actual reverse iteration bellow
var s = [];
for(i in a) {
    s.push(i);    
}
var total = s.length;
var totalMinusOne = total - 1;
for(i in 0...total) {
    trace(s[totalMinusOne - i]);    
}

是否有任何可能被用于去除阵列的可能性更多的优化?

iterator haxe
2个回答
3
投票

首先我与迪尤·摩根复制通过一个迭代扭转它产生的输出同意的,有点违背其宗旨(或至少它的一些好处)。有时候,不过没关系。

现在,关于技术的答案:

通过定义HAXE一个基本的迭代器只能计算出下一次迭代。

在为什么迭代器在默认情况下是片面的,这里就是我们可以看到:

  1. 如果所有,如果迭代器可以向后和向前跑,迭代器类将需要更多的时间来写。
  2. 不是所有的迭代器对集合或一系列数字的运行。

例如。 1:在标准输入运行的迭代器。

例如。 2:用于球的抛物线或更复杂的轨迹运行的迭代器。

例如。 3:略有不同,但想运行一个非常大的单链表的迭代器(例如类List)的性能问题。一些迭代器可以在迭代(Lambda.has()和Lambda.indexOf()例如,一旦有匹配返回的中间被打断,所以你通常不希望想起什么迭代的集合,但更如步骤可中断的系列或过程迭代步骤)。

虽然这并不意味着,如果你需要他们,你不应该定义两个方面的迭代器(我从来没有做过它HAXE,但它似乎没有不可能的),在绝对有两方面迭代器不自然,并执行迭代器是那样的复杂化将编码之一。

中间和更灵活的解决方案是简单有ReverseXxIter你需要,例如ReverseIntIter,或Array.reverseIter()(使用定制ArrayExt类)。所以,它的离开,我认为这是一个很好的平衡每一个程序员写自己的答案;同时,它需要更多的时间和挫折的开始(大家可能有同类的问题),你就会知道的语言更好,到底还有您刚才受益。


5
投票

它的错误我,你要复制的列表,但...这就是讨厌。我的意思是,数据结构应该已经是一个数组,如果这是它正确的数据格式。一个更好的东西(较少的内存碎片和再分配)不是一个数组(下称“[]”)将其复制到可能是一个链表或哈希。

但是,如果我们使用数组,然后将数组悟(http://haxe.org/manual/comprehension)是什么,我们应该使用,至少在HAXE 3或更好:

var s = array(for (i in a) i);

理想的情况下,至少对于那些多次访问迭代器大,S应该缓存。

要读取数据回来了,你可以改为做一些不那么罗嗦,但很讨厌的,如:

for (i in 1-s.length ... 1) {
    trace(s[-i]);
}

但是,这不是很可读,如果你的速度后,再创建一个全新的迭代器只是遍历数组是笨重进不去。相反,我宁愿稍长,但更清洁,可能更快的,大概少内存:

var i = s.length;
while (--i >= 0) {
    trace(s[i]);
}
© www.soinside.com 2019 - 2024. All rights reserved.