c# - 创建常量 IEnumerable<TSomeType>...的方法?

标签 c# .net performance memory c#-3.0

也许这是一个愚蠢的问题...但是创建常量IEnumerable<TSomeType> 的最佳(性能和内存方面)方法是什么? ...?

如果无法定义“最佳”方式,我有哪些选择?您的意见是什么,您认为有最合适的方法吗?

例如:

  • var enumerable = (IEnumerable<TSomeType>) new List<TSomeType> { Value1, Value2, Value3 };
  • var enumerable = (IEnumerable<TSomeType>) new TSomeType[] { Value1, Value2, Value3 };
  • (其他一些选项;例如 Linq Select)。

请考虑到内存和性能这里的一个问题 - 我们谈论的是一个真正受限的环境(安装了 .NET 的小型设备)。

提前致谢。

最佳答案

好吧,List<T>数组也不是不可变的,所以如果你真的追求不变性,它们就会被淘汰 - 调用者可以转换结果然后修改它。

您可以创建一个 List<T>并将其包装在 ReadOnlyCollection<T> 中.如果不再有对原始列表的引用,那么它实际上是不可变的,除非反射。

如果您实际上并不关心不变性 - 即,如果您相信所有代码都不会弄乱它 - 那么几乎可以肯定,数组将是性能最高的方法。有各种 CLR 级别的优化使它们工作得非常快。但是,在那种情况下,我不会转换为 IEnumerable<T> - 我只是将它作为一个数组公开。与编译器必须调用 GetEnumerator() 相比,这将使迭代更快。 .

如果 C# 编译器看到 foreach数组上的语句,它会生成调用以直接进入索引器并使用 Length属性... 然后 CLR 也将能够删除边界检查,发现模式。

同样,如果您决定使用 List<T> , 保留为 List<T> - 这样你就可以使用 List<T>.Enumerator - 这是一个结构 - 直接,没有装箱。

编辑:Steve Megson 提出了为此使用 LINQ 的要点。实际上,您可能会做得更好,因为一旦您获得了基础列表的枚举器,您就可以将 那个 安全地返回给调用者,至少对于我所知道的所有集合.所以你可以:

public class ProtectedEnumerable<T> : IEnumerable<T>
{
    private readonly IEnumerable<T> collection;

    public ProtectedEnumerable(IEnumerable<T> collection)
    {
        this.collection = collection;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return collection.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

这意味着迭代时只有一个 微小 命中 - 只是对 GetEnumerator() 的单个委托(delegate)调用.与使用 Enumerable.Select 进行比较,这将需要在 每个 调用 MoveNext() 时接受额外的委托(delegate)(以及无操作投影)。

关于c# - 创建常量 IEnumerable<TSomeType>...的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4091451/

相关文章:

c# - 如何在Winforms RichTextBox中实现基本的语法高亮?

c# - RegularExpressionValidator 正则表达式用于验证多行文本框中的 IP(每行一个)?

c# - 如何限制事件一次触发多次

c++ - 性能:找到 arr 中最大值的索引(允许并列)

c - 双倍性能比 C 中的 float 快得多

c# - 用户定义的属性是延迟加载还是急切加载

C# 屏幕分辨率和窗体显示

c# - 编码.UTF8 默认

c# - 基于云pubsub运行c#示例项目时的依赖问题

performance - 有谁知道像 twitter/facebook/Amazon 这样的网站是如何进行性能测试和调整的?