我无法理解Dart SDK中算法的有效性

时间:2013-07-05 17:59:44

标签: dart

我无法理解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);
  3. 但是在这种情况下创建列表#1是多余的,因为它是Iterable other的副本。它只会浪费CPU时间和内存。

    在这种情况下,此算法将更有效,因为它不会创建不必要的列表#1(growablefalse)。

    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;
      }
    

    或者我错了,错过了编程的一些细微之处?

2 个答案:

答案 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)

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

请参阅this committhis diff

该功能仅以

开始
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(注意,您需要首先跳过一些篮球,但是一旦你成立,这一切都很好。

也许值得向原始提交中的一个提交者或审阅者发送一个注释,让他们知道您的计划。