C#-听说有人不推荐使用Linq!?

先说结论

linq和直接遍历的性能差异点主要还是迭代方式数组字符串这类的foreach都是专门有优化的,而linq都是通用的泛型调用迭代器,如果刚好遇到这类数据又需要高性能就尽量不用linq,其他类型或性能要求不高的还是linq香。(ps:linq写的不好不能怪linq)

背景

起初是看到有人写的博客说***不推荐使用Linq!( https://mp.weixin.qq.com/s/FuF1Wp2eMxbamY5-uMErVQ ),还被多个wx订阅号转载,本能地觉得离谱呀!
what?!
unbelievable!

自测

仔细查看,发现这代码写的有问题呀,然后自己重写了一版

部分代码

    [Benchmark]public void SumWithLinq(){int sum = _row.Sum(c => c == ',' ? 0 : c-'0');}[Benchmark(Baseline = true)]public void SumWithLoop(){int sum = 0;for (int i = 0; i < _row.Length; i++){var c= _row[i];if (c!= ',')sum += c-'0';}}

测试结果

分析

虽然比那个博主的数据好了很多,但是linq确实比直接使用循环慢得多。查看Sum的内部实现,意料之中是用的迭代器,于是继续添加测试

再测

添加foreach测试代码

    [Benchmark]public void SumWithForeach(){int sum = 0;foreach (var c in _row){if (c != ',')checked{sum += int.CreateChecked(c-'0');}}}

测试结果

分析

foreach和for居然没有什么区别,那差距是在哪里呢?突然意识到sum的调用方是IEnumerable,于是又添加了如下测试

再测

添加测试代码

    [Benchmark]public void SumWithEnumerable(){int sum = 0;foreach (var c in _row as IEnumerable<char>){if (c != ',')checked{sum += int.CreateChecked(c-'0');}}}

测试结果

分析

直接对string做foreach和将string转为可迭代对象再foreach居然差这么多,string的foreach底层实现可能有优化

查看ILSpy

直接foreach:

调用迭代器:

深入了解foreach

参阅文档:.NET 本质论 - 了解 C# foreach 的内部工作原理和使用 yield 的自定义迭代器
https://learn.microsoft.com/zh-cn/archive/msdn-magazine/2017/april/essential-net-understanding-csharp-foreach-internals-and-custom-iterators-with-yield

附完整代码

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;internal class Program
{static void Main(string[] args){BenchmarkRunner.Run<LinqTest>();}
}[MemoryDiagnoser, MemoryRandomization]
public class LinqTest
{private static readonly string _row = "1,2,3,4,5,6,7,8,9,10";[Benchmark]public void SumWithLinq(){int sum = _row.Sum(c => c == ',' ? 0 : c-'0');}[Benchmark]public void SumWithEnumerable(){int sum = 0;foreach (var c in _row as IEnumerable<char>){if (c != ',')checked{sum += int.CreateChecked(c-'0');}}}[Benchmark]public void SumWithForeach(){int sum = 0;foreach (var c in _row){if (c != ',')checked{sum += int.CreateChecked(c-'0');}}}[Benchmark(Baseline = true)]public void SumWithLoop(){int sum = 0;for (int i = 0; i < _row.Length; i++){var c= _row[i];if (c!= ',')sum += c-'0';}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/738055.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

曙光服务器系统蓝屏数据恢复

一、蓝屏原因分析 首先,需要分析导致曙光服务器系统蓝屏的具体原因。蓝屏通常是由于操作系统或硬件设备驱动程序遇到致命错误所致。可能的原因包括软件冲突、硬件故障(如内存条问题、硬盘故障)、驱动程序过时或不兼容等。 二、安全措施 在进行数据恢复之前,务必确保服务器的…

服务器存储金蝶数据库丢失恢复

一、检查备份情况 确认备份存在: 首先,需要确认是否有金蝶数据库的备份存在。备份是数据恢复的基础,没有备份的情况下恢复数据将非常困难。 检查备份的完整性和时效性: 验证备份文件的完整性和时效性,确保备份文件没有损坏且包含丢失数据之前的数据库状态。二、使用备份恢…

威联通NAS维修

涉及多个方面,包括硬件故障维修、数据恢复等。 一、维修内容 硬件故障维修: 针对威联通NAS出现的各种硬件故障,如电源故障、主板故障、硬盘故障等,提供检测和维修。 在维修过程中,会仔细检查每个部件,确保找到故障根源并进行修复。 数据恢复: 当威联通NAS中的数据因硬盘…

Fastapi 脚本接口规范优化

Fastapi 脚本接口规范优化 在编写Fastapi脚本提供自动化接口操作时,我们不仅要实现接口功能实用性,也要考虑接口的规范管理,这边以Fastapi官方文档作为一个切入点。 官方接口文档 默认官方接口文档如下图所示,宛如大杂烩一样 /doc接口文档 /redoc接口文档 优化方案 1、根据…

面试官:Java类是如何被加载到内存中的?

类的生命周期都有哪些阶段?类加载的过程是怎样的?面试连环callJava类是如何被加载到内存中的? Java类的生命周期都有哪些阶段? JVM加载的class文件都有哪些来源? JVM在加载class文件时,何时判断class文件的格式是否符合要求?类生命周期 一个类从被加载到虚拟机内存开始,…

招募贴 | 第四期自动驾驶OS开发初阶营报名开启

招募贴 | 第四期自动驾驶OS开发初阶营报名开启 第四期国家智能网联汽车创新中心自动驾驶OS开发初阶训练营将于2024年7月22日开营,现已开启报名,诚邀对自动驾驶底层软件开发感兴趣的学员加入,一起驶入自动驾驶的快车道,共同探索未来的无限可能。从训练营能学到什么? 训练营…

STM32L073RZT 调试SPI问题

现象描述: spi通信一次后,第二次通信spi的SR寄存器异常0xFF31(MODF, CRCERR, RXNE),通信失败。 以下为调用流程及相关代码:NFC_ID(); NFC_REG_B_TEST();//SPI 读 void SPI_Read_Data(uint8_t* w_data, uint32_t w_size, uint8_t* r_data, uint32_t r_size) {SET_SPI_CSS(G…

Spark大数据处理:技术、应用与性能优化(全)PDF书籍推荐分享

本书从一个系统化的视角,秉承大道至简的主导思想,介绍Spark中最值得关注的内 容,讲解Spark部署、开发实战,并结合Spark的运行机制及拓展,帮读者开启Spark技术之旅。 Spark大数据处理:技术、应用与性能优化(全)PDF下载 Spark已经在全球范围内广泛使用,无论是Intel、Yahoo…

LaTeX 编辑协作平台 Overleaf 安装和使用教程

在学术界和科技行业,LaTeX 已成为撰写高质量文档的标准工具。然而,传统的 LaTeX 使用体验常常伴随着以下挑战:学习曲线陡峭 环境配置复杂 多人协作困难 实时预览不便当然,市面上不乏很多在线 LaTeX 编辑平台,但它们大多是封闭的商业服务,无法完全满足用户对数据隐私和自主…

半个月6次面试,终于进百度HR面了

和大家分享一下来自粉丝的面经投稿,他在最近半个月内疯狂的面试,光百度就约面了两个岗位,一共进行了6场面试,并且其中一个进到了 HR 面。今天和大家分享一下来自粉丝的面经投稿,他在最近半个月内疯狂的面试,光百度就约面了两个岗位,一共进行了6场面试,并且其中一个进到…

使用钉钉Oauth2授权登录Odoo配置

准备工作 需要用到的模块: Odoo/auth_oauth OCA/server-auth/auth_oidc 因为钉钉的Oauth授权流程比较特殊,需要继承改造res.users上的几个方法 models\res_users.pyclass ResUsers(models.Model):_inherit = "res.users"dingtalk_userid = fields.Char(Dingtalk Us…

推荐一款Win11主题WPF UI框架

最近在微软商店,官方上架了新款Win11风格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,这款应用引入了前沿的Fluent Design UI设计,为用户带来全新的视觉体验。最近在微软商店,官方上架了新款Win11风格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,这款应用引入了前沿的…

图论总结

重链剖分 树上修改,查询路径信息之类的 最多经过logn个轻边, 这样可以更好地划分 注意点: 修改边权可以转化到点权上面: 注意lca的位置不要修改, 应该是update(id[y]+1,id[x]) 例题: 轻重边: https://www.luogu.com.cn/problem/P7735 判断是不是重边,信息转化到点上面,…

logstach 8.6.2输出到mongo 6

logstach官网下载:https://www.elastic.co/cn/downloads/past-releases 1、查看logstach有没有自带输出到mongo的插件,到logstach安装目录/bin下cd /data/logstash-8.6.2/bin/ ./logstash-plugin list --verbose2、没有自带输出到mongo的插件就安装./logstash-plugin install…

模拟集成电路设计系列博客——8.4.3 数控振荡器

8.4.3 数控振荡器 在之前的章节中,我们介绍了一种简单得基于LC振荡器得数控振荡器方式,通过开关控制谐振电路中的电容值实现数控频率方式。 另一种更直接的利用模拟PLL中的LC振荡器VCO的方式是直接通过DAC的方式将数字码转换成模拟量,然后对电容施加控制。值得一提的是这种压…

android 性能优化 -systrace

简介: Systrace允许监视和跟踪Android系统的行为(trace)。它会指明系统都在哪些工作上花费时间、CPU周期都用在哪里,甚至可以看到每个线程、进程在指定时间内都在干嘛。它同时还会突出观测到的问题,从垃圾回收到渲染内容都可能是问题对象,甚至提供建议的解决方案。但是不能…

故地重游

近来,种种原因让我总觉得对任何事都失去了兴趣,整个人犹如失去灵魂的躯壳一般。一切都在往前走,但我想更快一些却无能为力,比较稳定的环境也就注定了过程的时长,又没有改变当下的勇气,每每思量心猿四起,无法自拔。本诗在故地重游(初到京第一工作地)所做,一步步走在那…

pip安装问题记录

【问题1】 pip安装某第三方库的时候报错:metadata-generation-failed解决办法: 1、确保你的pip和setuptools是最新版本:pip install --upgrade pip setuptools 2. setuptools版本不适配,不能进行构建: pip install --upgrade setuptools==57.5.0

P2286 [HNOI2004] 宠物收养场 题解

P2286 [HNOI2004] 宠物收养场 题解 set 做法P2286 [HNOI2004] 宠物收养场 set做法 题链\(_{洛谷}\) \(_{题库}\) 思路 一眼查找前驱后继的题。注意到一句话:那么用 set 就没有什么阻碍了,方便又快捷。 题意很简单,若宠物多则查找与人需求最接近的上下两个值,人多则找与宠…

Dijkstra算法理解-无人机路径规划

1、理解 Dijkstra算法是路径规划算法中非常经典的一种算法,在很多地方都会用到,特别是在机器人的路径规划中,基本学习机器人运动相关的都会接触到该算法。 Dijkstra算法本身的原理是基于贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的…