2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

讨论:泛型是否会对性能产生负面影响

  • 2009-05-30
  • 本文字数:1861 字

    阅读完需:约 6 分钟

正值端午传统节日,在国内知名的.NET 技术社区博客园中进行了一场较为激烈的讨论。讨论话题围绕:.NET 中的泛型是否会影响性能。

飞林沙的一篇文章《从 dynamic 到特性误用》引起了这场讨论。在这片文章中,飞林沙指出 C# 4.0 新增的 dynamic 关键字会对程序性能的影响,呼吁大家仅在合适的时候使用 dynamic 新特性。可能是由于社区中对于 C# 4.0 的新特性还不太关注,这个问题本身的反响不大。反而是文章所引发的一个周边话题引起了网友的兴趣。

在文章的结尾,飞林沙认为太多开发人员并没有了解新特性的优劣就盲目追逐,并举出他所认为的一个泛型错误做法:

……我看到有人在代码中使用 List而不是 ArrayList,我不明白这种做法除了降低性能之外还有什么好处……

文章发表不久,便有网友对此观点产生质疑,认为“泛型是生成新的类型,拿来的效率影响之说”,不过也有网友表示“.NET 的泛型会略微影响效率,跟 C++ 略有些不同”。在 Jeffrey Zhao 发表了一篇性能比较文章之后,围绕这个话题的讨论便由此展开。

Jeffrey Zhao 的文章《泛型真的会降低性能吗?》使用代码来统计常用操作所消耗的时间,试图发现泛型容器对性能的影响。除了.NET 类库中经典的 ArrayList 和 List类型之外,他还编写了最简单的 MyArrayList 和 MyList两个类型,目的是避免其它任何实现方面的细节对性能的影响。对于长度为 100 的容器,各执行 30 万次操作的结果如下表所示:

使用 for 进行下标遍历 使用 foreach 进行遍历 MyArrayList 2,398ms 21,367ms MyList 2,285ms 3,463ms ArrayList 2,282ms 5,187ms List 2,302ms 2,989ms 根据实验结果,Jeffrey Zhao 得出了以下结论:

……泛型的 MyList 性能甚至略比 MyArrayList 有所提高。当然测试的结果其实是互有胜负,但是事实上,MyList 的获胜的次数甚至还略有领先……从结果上已经可以看出,泛型并不会影响性能,而 List的性能也不比 ArrayList 要差……

Jeffrey Zhao 同时呼吁“在有泛型支持的情况下,尽量使用泛型容器。例如使用 List而不是 ArrayList”:

……除了“性能”之外,老赵的还有其他一些理由。例如使用 List的话就可以使用框架内部所定义的各种有用的辅助方法(要知道在.NET 框架中,现在几乎都是在针对 IEnumerable进行开发);而我们平时写程序时,也可以统一的针对泛型编程,如 IList,IEnumerable,不必考虑 List 或 Enumerable 等非泛型元素。

Jeffrey Zhao 的测试结果得到了大部分网友的承认,不过也有部分网友对这个实验的部分做法有所质疑。如开源框架 NBear 的创始人 Teddy Ma 认为 MyArrayList 的 foreach 操作慢的原因在于非泛型的 IEnumerator 内部对于数组使用 Array.GetValue(Int32) 来获取对象,而泛型的 IEnumerator则直接使用数组下标进行访问:

……如果都用 for 而不是 foreach,我想应该非泛型略快一点点。

对此,Jeffrey Zhao 回应道:

……我测试的都是平时的常用操作,黑盒测试,没有故意去走某个特别慢的路径。……看来内部实现的造成问题,可惜我们平时都是用这个做法,因为是框架自带的。

为什么总是说泛型性能会差一些?测试结果都摆在这里了。根据测试结果,就算是下标访问,泛型也不差。……所以结论还是不变,能够用 List就不要用 ArrayList。

稍后又有网友引用了国外网友 Rico Mariani 的文章回复中总结的观点,认为 ArrayList 比 List性能差的原因在于:

  1. ArrayList 中使用了大量的虚方法,.NET 框架设计团队不反对我们继承 ArrayList 实现新的集合类型。这种做法也影响了 JIT 对方法的内联。
  2. ArrayList 的遍历器实现较为复杂,会构造大量的 Enumerator 对象。而在.NET 2.0 中新设计的 List类型简化了这部分代码,获得了较高的性能。

至此,大家基本已经达成共识,ArrayList 性能较差是由于内部实现逻辑的影响,在实际开发过程中使用 List能够获得更好的性能。不过,还是有一些网友“普遍认为”,抛开泛型对值类型装箱 / 拆箱的性能优化,纯粹的泛型容器性能还是会略低于非泛性的 Object 容器。不过,Jeffrey Zhao 新发表的一篇文章似乎从根本上推翻了这个看法。

在《从汇编入手,探究泛型的性能问题》一文中,Jeffrey Zhao 使用 WinDbg 查看了 MyArrayList 和 MyList的下标 get 方法,在 JIT 之后所生成的汇编代码,并加以详细的分析和对比。比较的结果发现,两者除了几个地址不同之外,在执行时所经过的指令几乎完全相同,以此有力地证明了“泛型并不会影响程序性能”。

在问题的讨论过程中也产生了一些额外的话题,例如究竟应该使用 for 和下标访问,还是 foreach 来遍历一个容器,还有一个应用程序是否应该在这样的地方追求性能提升。

您的看法是什么呢?

2009-05-30 20:193918
用户头像

发布了 157 篇内容, 共 62.3 次阅读, 收获喜欢 6 次。

关注

评论

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

ByteSRC奖励再升级,单个重大漏洞提升至10万元

极客天地

如何定期清理数据库中的无效数据?

NineData

数据清理 数据归档 NineData 无效数据 优化数据库

开放原子开源大赛—基于OpenHarmony的团结引擎应用开发赛正式启动!

OpenHarmony开发者

网络安全等级测评师考试培训可以参考哪些资料?

行云管家

等保 等级保护 等保测评师

万字带你了解ChatGLM

华为云开发者联盟

人工智能 华为云 大模型 华为云开发者联盟

带你走进 HarmonyOS:前端如何迎接新技术的到来

京东科技开发者

代币开发:2024年代币开发主要因素

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

「飞桨星河社区创作者激励计划」全新上线!丰富权益,等你领取~

飞桨PaddlePaddle

百度 开发者社区 百度飞桨 星河社区 飞桨星河社区

【一文读懂】基于Havenask向量检索+大模型,构建可靠的智能问答服务

阿里技术

向量检索 LLM 智能问答 Havenask 召回搜索引擎

提升地理空间分析效率,火山引擎ByteHouse上线GIS能力

字节跳动数据平台

数据库 大数据

等保测评与信息安全管理体系认证的区别

行云管家

等保 等级保护 等保测评

Tapjoy from Unity 推出“每日奖励”积分墙广告,以增强用户粘性并提升投放 ROAS

极客天地

ppt美化ai软件有哪些?这5款AI工具一键生成PPT!

彭宏豪95

人工智能 PPT AIGC 效率软件 AI生成PPT

十分钟掌握分布式数据库开发:OpenMLDB 开发者镜像详解

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征

2024-03-13:用go语言,给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q =

福大大架构师每日一题

福大大架构师每日一题

软件测试岗位我是如何拿到5个offer的一些经验分享(附面试题)

测试人

软件测试 面试题

软件测试学习笔记丨服务端问题定位常用linux指令集合

测试人

Linux 软件测试

代码精简执行过程

京东科技开发者

面试八股文,自有其道理

老张

面试 专业能力

一个数据库死锁竟然被测试发现了,这你敢信

京东科技开发者

[自研开源] MyData v0.7.2 更新日志

LIEN

开源 数据集成 业务融合 API对接 mydata

即时通讯技术文集(第35期):IM群聊技术合集(Part2) [共12篇]

JackJiang

即时通讯;IM;网络编程

一键开启 GPU 闲置模式,基于函数计算低成本部署 Google Gemma 模型服务

阿里巴巴云原生

阿里云 云原生 函数计算

数据“隐领”未来!【隐私计算实训营】限时免费招募!

隐语SecretFlow

数据分析 数据安全 隐私计算

超越基础设施:深度探讨平台工程的关键支柱

SEAL安全

架构 基础设施 平台工程

npm是如何处理多版本依赖的?

伤感汤姆布利柏

【体验有奖】用 AI 画春天,函数计算搭建 Stable Diffusion WebUI

阿里巴巴云原生

阿里云 云原生 AIGC

以守为攻,零信任安全防护能力的新范式

权说安全

零信任

为了跳槽或提升自己,你会先学习哪一门编程语言?

小魏写代码

得物布局构建耗时优化方案实践

得物技术

xml 前端

讨论:泛型是否会对性能产生负面影响_.NET_赵劼_InfoQ精选文章