写点什么

高性能的.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:122174
用户头像

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

关注

评论

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

创新驱动数字经济发展,融云获评「2023 数字经济隐形独角兽」

融云 RongCloud

数字化转型 数字经济 办公 融云 政企

语音数据集:推动智能语音技术发展的关键驱动力

来自四九城儿

将 Python 和 Rust 融合在一起,为 pyQuil® 4.0 带来和谐

Swift社区

rust Python Monad

MAMP PRO for Mac v6.8.1永久激活版 专业的Web开发环境

iMac小白

场外白名单达到1200U?Solana 生态铭文跨链桥 Sobit 是何神圣?

大瞿科技

从BERT到ChatGPT:预训练大模型的演变与突破

百度开发者中心

人工智能 nlp 大模型

知识图谱技术在金融领域的分析和应用

悦数图数据库

图数据库 知识图谱

ubuntu20.4服务器安装mysql社区版并开放3306端口

百度搜索:蓝易云

MySQL 云计算 Linux ubuntu 运维

Solana 生态铭文跨链桥 Sobit 是何神圣?其场外白名单已达到1200U

西柚子

Radio Silence for mac(简单好用的防火墙)v3.2激活版

iMac小白

ABBYY FineReader PDF 15 for Mac(ocr文字识别软件)v15.2.13中文激活版

iMac小白

赛博威新一代TPM营销费用管理指南——费用管理类型篇

赛博威科技

数字化转型 营销费用管理 赛博威 销售费用管理 费用管理类型

【Linux】硬件性能测试工具安装。

百度搜索:蓝易云

云计算 Linux 运维 服务器 云服务器

TI 专访 Merlin Protocol:构建在比特币网络上的资产适配协议

TerpLayer

BERT实现多标签文本分类:强大模型的应用与展望

百度开发者中心

自然语言处理 大模型 LLM

软通咨询助力某新能源头部企业迈向高效数智化时代,塑造行业新典范

软通咨询

数据智能 数字化咨询

Amazon Q | 融会贯通的 AI 开发助手来了!

亚马逊云科技 (Amazon Web Services)

人工智能 re:Invent 生成式人工智能 Amazon Q Amazon CodeCatalyst

RWKV: 轻松实现大模型本地私有化部署

百度开发者中心

人工智能 深度学习 大模型

ETLCloud X 明道云实现无缝数据连接

RestCloud

数据同步 ETL 明道云

WAVE SUMMIT+ 2023 今日开场!奉上完整预告和参会指南,今天见!

飞桨PaddlePaddle

人工智能 深度学习 开发者 WAVE SUMMIT

做好数据管理体系 发挥企业数据乘数效应

用友BIP

数据

如何在敏捷项目中实现高效测试?

敏捷开发

项目管理 敏捷开发 测试左移 测试自动化 bug管理

mac电脑强大电脑风扇转速管理:Macs Fan Control Pro激活码中文版

胖墩儿不胖y

Mac软件 电脑风扇软件 风扇转速软件

Topaz Video AI for mac(视频增强和修复工具) 4.0.8完整激活版

mac

苹果mac Windows软件 Topaz Video AI

软件测试/测试开发丨SQL多表查询 学习笔记

测试人

sql 软件测试 测试开发

火山引擎边缘云获“2023边缘计算年度领航企业”及“最佳CDN创新企业”等多项荣誉

火山引擎边缘云

CDN 边缘计算 边缘云 CDN技术

软件开发

Geek_8da502

IPQ6000 IPQ6010 VS IPQ5018|A Comprehensive Comparison: Evaluating Wallys' WiFi 6 SoCs Offering

wallyslilly

IPQ6010 IPQ6000 ipq5018

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