最新发布的.NET不可变集合中包含了ImmutableArray<T>,一种在只读、索引化的场景中比ImmutableList<T>更快速的选择。ImmutableList<T>在设计时选择了一种平衡的方案。由于其复杂的内部结构,添加新项只能是O(log n)的操作。同样,通过索引读取某项也要耗费O(log n)的时间。
ImmutableArray<T>则没有这么复杂。它只是一个包装了数组的结构。用ildasm可以看到,它不包含任何其他字段。这意味着从不可变数组中读取只需要O(1)的时间。相反,向不可变数组添加一项则需要对实际数组进行完全拷贝,为O(n)操作。
Immo Landwerth提出了以下建议:
使用不可变数组的理由:
仍然使用不可变列表的理由:
|
作为一个值类型,ImmutableArray<T>在创建时不需要显式初始化。此时,结构将检测到内部空指针,其行为就像是长度为0的数组。
重大改变不可变集合正处于开发过程中,重大变更时有发生。这一次,我们看到Create<T>(IEnumerable<T> items)函数更名为“From”。
Immo写到,
我们发现接受IEnumerable<T>参数的重载可能会产生意想不到的结果。你可能认为要通过其他集合创建集合可以使用接受IEnumerable<T>参数的重载: 但你最终创建的是ImmutableList<List<string>>而不是Immutable<string>,这是因为在进行重载决策时,参数重载的优先级要高于从List<string>到IEnumerable<string>的隐式转换。 因此我们决定将所有操作IEnumerable<T>的工厂方法改名为From,以消除这种歧义。 |
最初的IImmutableList<T>包含一个ValueComparer属性,并匹配WithComparer方法。为了让ImmutableArray<T>保持为一个简单的包装器,就有必要在IImmutableList<T>接口中移除它们。
扩展方法GetValueOrDefault曾经接受一个IDictionary<TKey, TValue>或IReadOnlyDictionary<TKey, TValue>。如果实际的类同时实现了这两个接口就会引起编译器错误,因此用只接受IImmutableDictaionary<TKey, TValue>的版本进行了替换。
其他改变IImmutableSet<T>新增了TryGetValue方法。如果使用了比较器如StringComparer.OrdinalIgnoreCase,并且想得到集中的实际值而不仅仅是判断是否存在等价的元素时,就需要使用该方法了。
不可变集合仍然是预览版,并且不允许在生产中使用。它们目前可用于.NET 4.5、Windows Store、Windows Phone 8和Portable Class Library。
数组的性能Jon Skeet最近测试了数组的性能并发现了一些有趣的结果。用包装器包装数组竟然可以使它们能够更快地写入。对一个包含100项的数组进行1亿次写入,字符串数组用了40.865秒,而包装的字符数组只用了29.338秒。读取速度两者差不多,字符数组用了12秒,包装的数组用了11.843秒。
其原因要追溯到Java了。Java的数组是协变的,也就是说可以将一个String[]传递给任何期望Object[]的参数或变量。.NET的运行时CLR要设计为支持Java,所以也支持协变数组。因此在每次写入数组时CLR都需要执行一次类型检查。
Jon Skeet的数组包装器与我们上面提到的ImmutableArray中使用的并不相同。它在内部对数组中的每一项使用了基于结构的包装器。由于它只是一个包含了指针的结构,因此并不比数组中存储的普通引用耗费更多的空间。但其设计可以使CLR的JIT编译器忽略类型检查。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
.NET架构师:函数式语言做领域驱动设计
Scott一位.NET架构师,同时也是掌握函数式编程的作者,他很欣赏函数式编程,对于Scott来说,面向对象编程的那些概念也很恐怖,比如多态、泛型、继承、协变等。
-
软件开发就像炒股 关键看你怎么选股票!
本文作者Paulo Ortins在这里分享了对于选择哪种编程语言作为软件开发工作的起点的话题,并阐述了自己的观点。
-
增进离岸Java开发效率的十个提示
近日,Cygnet Infotech公司发布了一篇博文,谈到了如何增进离岸Java开发的效率。众多的ISV与软件厂商总是在不断寻找能以最低的代价实现其业务目标的解决方案。
-
Visual Studio 2013增强调试功能
Visual Studio 2013包含了若干诊断特性,能够帮助开发人员有效地调试他们的应用程序。