我无法理解Dart SDK中算法的有效性。
以下是算法(dart:core
中的列表工厂,文件list.dart
)
factory List.from(Iterable other, { bool growable: true }) {
List<E> list = new List<E>();
for (E e in other) {
list.add(e);
}
if (growable) return list;
int length = list.length;
List<E> fixedList = new List<E>(length);
for (int i = 0; i < length; i ) {
fixedList[i] = list[i];
}
return fixedList;
}
如果growable
为false
,则会创建两个列表。
List<E> list = new List<E>();
List<E> fixedList = new List<E>(length);
但是在这种情况下创建列表#1是多余的,因为它是Iterable other
的副本。它只会浪费CPU时间和内存。
在这种情况下,此算法将更有效,因为它不会创建不必要的列表#1(growable
是false
)。
factory List.from(Iterable other, { bool growable: true }) {
if(growable) {
List<E> list = new List<E>();
for (E e in other) {
list.add(e);
}
return list;
}
List<E> fixedList = new List<E>(other.length);
var i = 0;
for (E e in other) {
fixedList[i++] = e;
}
return fixedList;
}
或者我错了,错过了编程的一些细微之处?
答案 0 :(得分:2)
我们通常避免在iterables上调用length
getter,因为它可以具有线性性能和副作用。例如:
List list = [1, 2, 3];
Iterable iterable1 = list.map((x) {
print(x);
return x + 1;
});
Iterable iterable2 = iterable1.where((x) => x > 2);
var fixedList = new List.from(iterable2, growable: false);
如果List.from
调用length
getter,它将在所有元素上运行两次(where
不会缓存其结果)。它还将执行两次副作用(打印1,2,3)。有关Iterables的更多信息,请查看here。
最终我们想要更改List.from
代码,以便我们避免第二次分配和复制。为此,我们需要(内部)功能将可增长列表转换为固定长度列表。跟踪错误:http://dartbug.com/9459
答案 1 :(得分:1)
看起来它只是对现有功能的增量更新。
该功能仅以
开始List<E> list = new List<E>();
for (E e in other) {
list.add(e);
}
并添加了一些位作为fairly major refactoring of numerous libraries的一部分。
我想说最好的办法是在dartbug.com上提出错误报告,然后添加补丁或提交CL - 请参阅此处的说明:https://code.google.com/p/dart/wiki/Contributing(注意,您需要首先跳过一些篮球,但是一旦你成立,这一切都很好。
也许值得向原始提交中的一个提交者或审阅者发送一个注释,让他们知道您的计划。