【问题标题】:How this ToArray() implementation more optimized?这个 ToArray() 实现如何更优化?
【发布时间】:2012-09-05 00:09:24
【问题描述】:

我只是查看了我们代码库的历史记录,并发现了一个与此不同的签入:

    public virtual T[] ToArray()
    {
        List<T> list = new List<T>();
        foreach (object item in List)
        {
            list.Add((T)item);
        }

        return list.ToArray();
    }

到这里:

    public virtual T[] ToArray()
    {
        T[] result = new T[List.Count];
        for (int i = 0; i < List.Count; ++i)
        {
            result[i] = (T)List[i];
        }

        return result;
    }

附注:优化ToArray实现,避免在过程中创建多个数据结构。

我想知道为什么这里有优化。 for() 可能比foreach() 快​​,但是“创建多个数据结构”在哪里?

P/S:写这篇文章的人现在正在度假

【问题讨论】:

  • 我看到的最大优化是避免使用列表,而只是在整个过程中坚持使用数组

标签: c# .net arrays optimization


【解决方案1】:

在原始代码中,您创建了一个 List&lt;T&gt; - 未指定容量,因此可能涉及多次复制内部数组 - 然后您在 List&lt;T&gt; 上调用 ToArray,从而生成一个副本。

较新的版本没有这样做。它创建一个数组,并将原始列表复制到其中。

诚然,仅使用 LINQ 的 ToArray 方法会更简单,甚至可能更有效,但不清楚为什么这是一个虚拟方法开始,但是...

【讨论】:

    【解决方案2】:

    第一个实现创建了一个中间人额外的 List 对象; GC 清理只是另一件事。这种优化几乎肯定不会引起注意,除非这个例程被击中到非常高的水平。

    否则与使用foreach还是for无关。这种选择主要是因为列表在被枚举时不能被修改的规则。

    【讨论】:

    • 在构建这样的数组时使用foreach 会很尴尬,因为您仍然需要保留索引才能知道在哪里写入 到数组。
    【解决方案3】:

    为了更快地将 List 转换为 Array,HPCsharp nuget 包实现了 List.ToArray() 的并行(多核)版本:

    public virtual T[] ToArray()
    {
        return List.ToArrayPar();
    }
    

    这个方法不是必须的,只要使用 List.ToArrayPar() 函数,只要需要一个数组。这个并行版本比 List.ToArray() 快大约 3 倍

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多