2

我无法理解 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;
  }

如果growablefalse,则将创建两个列表。

  1. List<E> list = new List<E>();
  2. List<E> fixedList = new List<E>(length);

但是在这种情况下创建列表 #1 是多余的,因为它是Iterable other. 它只是浪费CPU时间和内存。

在这种情况下,该算法将更有效,因为它不会创建不必要的列表#1 ( growableis 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;
  }

还是我错了,错过了一些编程的微妙之处?

4

2 回答 2

2

我们通常避免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调用lengthgetter,它将在所有元素上运行两次(where不缓存其结果)。它还会执行两次副作用(打印 1、2、3)。有关 Iterables 的更多信息,请查看此处

最终我们想改变List.from代码以避免第二次分配和复制。为此,我们需要将可增长列表转换为固定长度列表的(内部)功能。跟踪错误:http ://dartbug.com/9459

于 2013-07-05T20:30:36.927 回答
1

看起来这只是对现有功能的增量更新。

查看此提交此差异

该功能刚刚开始

List<E> list = new List<E>();
for (E e in other) {
  list.add(e);
}

并在对众多库进行相当重大的重构时添加了更多位。

我想说最好的办法是在 dartbug.com 上提出错误报告,然后添加补丁或提交 CL - 请参阅此处的说明:https ://code.google.com/p/dart/wiki /Contributing (请注意,您确实需要先跳过一些障碍,但是一旦设置好,一切都很好)。

还可能值得在原始提交中给其中一位提交者或审阅者留个便条,让他们知道您的计划。

于 2013-07-05T19:25:13.597 回答