写点什么

高性能的.NET 不可变数组

  • 2013-07-05
  • 本文字数:1401 字

    阅读完需:约 5 分钟

最新发布的.NET不可变集合中包含了 ImmutableArray,一种在只读、索引化的场景中比 ImmutableList更快速的选择。ImmutableList在设计时选择了一种平衡的方案。由于其复杂的内部结构,添加新项只能是 O(log n) 的操作。同样,通过索引读取某项也要耗费 O(log n) 的时间。

ImmutableArray则没有这么复杂。它只是一个包装了数组的结构。用 ildasm 可以看到,它不包含任何其他字段。这意味着从不可变数组中读取只需要 O(1) 的时间。相反,向不可变数组添加一项则需要对实际数组进行完全拷贝,为 O(n) 操作。

Immo Landwerth 提出了以下建议:

使用不可变数组的理由:

  • 极少更新数据,并且元素数量很小(小于 16)
  • 对迭代数据的性能要求很高
  • 有很多不可变集合的实例,并且无法负担将它们全放在树中的开销。

仍然使用不可变列表的理由:

  • 更新数据比较常见,或者元素数量预计不会太小
  • 对更新集合的性能要求比迭代要高

作为一个值类型,ImmutableArray在创建时不需要显式初始化。此时,结构将检测到内部空指针,其行为就像是长度为 0 的数组。

重大改变

不可变集合正处于开发过程中,重大变更时有发生。这一次,我们看到 Create(IEnumerable items) 函数更名为“From”。

Immo 写到,

我们发现接受 IEnumerable参数的重载可能会产生意想不到的结果。你可能认为要通过其他集合创建集合可以使用接受 IEnumerable参数的重载:

但你最终创建的是 ImmutableList<List> 而不是 Immutable,这是因为在进行重载决策时,参数重载的优先级要高于从 List到 IEnumerable的隐式转换。

因此我们决定将所有操作 IEnumerable的工厂方法改名为 From,以消除这种歧义。

最初的 IImmutableList包含一个 ValueComparer 属性,并匹配 WithComparer 方法。为了让 ImmutableArray保持为一个简单的包装器,就有必要在 IImmutableList接口中移除它们。

扩展方法 GetValueOrDefault 曾经接受一个 IDictionary<TKey, TValue> 或 IReadOnlyDictionary<TKey, TValue>。如果实际的类同时实现了这两个接口就会引起编译器错误,因此用只接受 IImmutableDictaionary<TKey, TValue> 的版本进行了替换。

其他改变

IImmutableSet新增了 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 编译器忽略类型检查。

查看英文原文 High Performance Immutable Arrays in .NET

2013-07-05 06:122224
用户头像

发布了 59 篇内容, 共 23.6 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

2021最新38道Spring大厂面试题,你碰到过哪道?,java开发工程师百度百科

Java 程序员 后端

发布两小时,霸榜GitHub Spring Boot实战文档

Java GitHub spring 编程 程序员

博睿数据APM适配欧拉开源操作系统,为开发者性能体验保驾护航

博睿数据

云开发CloudBase集成腾讯数字身份管控平台CIAM,快速实现账号管理

腾讯安全

通用排序框架在爱奇艺推荐的应用

爱奇艺技术产品团队

数字化学习分享+一场思维探索工作坊+引导回顾会+公开演讲

研发管理Jojo

数字化转型 敏捷教练 咨询

从开始到放弃:某高校电子校友卡开发笔记

CC同学

模块三作业

panxiaochun

架构实战营

今天面了个腾讯拿 38K 出来的,让我见识到了基础的天花板

Java 程序员 JVM springboot MyBatis标签

网易云音乐网络库跨平台化实践

网易云信

数据库 网络库 跨平台化

2021年10月券商App行情刷新及交易体验评测报告,兴业证券荣登榜首!

博睿数据

2021最新一线互联网大厂常见高并发面试题解析,springcloud视频百度云

Java 程序员 后端

【福利】腾讯WeTest专有云,限时开放招募体验官

WeTest

全捐了,华为将欧拉开源操作系统代码、品牌等相关资产捐赠!!!

WorkPlus

2021最新华为面经分享:Java高分面试指南(25分类1000题50w字解析)

Java 程序员 后端

WeTest与腾讯安全联合推出小程序质量方案,助力私域流量2.0新增长

WeTest

不愧是GitHub上标星120K的Java手册,全程干货,只讲重点

收到请回复

Java 程序员 后端 面试技巧

万字长文手写数据库连接池,让抽象工厂不再抽象

Tom弹架构

Java 架构 设计模式

大数据实践:数据指标中心的建设思路

大数据技术指南

11月日更

元宇宙让我们实现“办公自由”?想要远程办公,保证员工效率和有效管理才是关键!

极狐GitLab

WorkPlus移动门户开启数字化智慧办公新模式

WorkPlus

Gartner:对中国央行数字货币的创新见解

WorkPlus

送给正在入行的小白:最全最有用的网络安全学习路线已经安排上了

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

2021最新出炉BAT架构实战文档:多线程与高并发+分布式+微服务,泛微网络java面试题

Java 程序员 后端

2021最新常见200+Java面试题汇总(含答案解析),unity高级工程师面试题

Java 程序员 后端

完美诠释Netty,腾讯强推599页Netty进阶神技,惊掉我的下巴

Java 编程 程序员 Netty

百度APP移动研发平台及DevOps实践

百度开发者中心

DevOps 最佳实践 方法论 移动端 百度app

爱奇艺基于SpringCloud的韧性能力建设

爱奇艺技术产品团队

阿里内网疯狂传阅的“M8级”分布式架构笔记,GitHub刚上线就霸榜

Java 编程 程序员 架构 阿里

CSS页面设计稿构思与实现(四)之自定义字体

Augus

CSS 11月日更

质量基础设施一站式云服务平台搭建,NQI一站式服务平台

电微13828808271

高性能的.NET不可变数组_.NET_Jonathan Allen_InfoQ精选文章