LINQ 和性能

news/2024/11/27 11:34:01/

介绍

自从微软在 .NET 3.5 中引入LINQ已经 15 年(2007 年) 。这应该有足够的时间让它成熟为一个全方位的有用工具。

LINQ的使用有几个方面:

  • 延迟执行和延迟评估(更好地利用多线程系统)
  • 缩短代码(可读性和可重用性)
  • 所用技术的运行时开销(性能)

在本文中,我将只了解 LINQ 的一个方面——性能。

背景

LINQ - 至少在我的环境中 - 以其外观使所有 C# 程序员兴奋不已,随后导致该技术的大量使用。

我想在这里问一下,如果一个人完全清醒地看待 LINQ:作为扩展方法和匿名委托(lambda 表达式)与延迟执行(yield)的创新组合,还有多少营销亮点?

为了从性能方面回答这个问题,我想用 LINQ 过滤一个对象列表并对结果进行排序。

这种方法的特殊性是 LINQ 必须处理列表直到最后一个元素。因此,我有意消除Any()使用or可以实现的运行时优势,First()并专注于必须处理所有元素的情况。

测试

当然,结果取决于底层运行时系统、操作系统和硬件的多线程能力——因此,仅将在同一环境中运行的不同方法相互比较是有用的。为此,我准备了 4 个可以相互比较的测试用例。

  • 测试用例 1:使用 C++ 的 LINQ(无排序和有排序)
  • 测试用例 2 :使用 C++ 的经典(for(...)循环if(...)和)(无排序和有排序)sort(...)
  • 测试用例 3:使用 C# 的 LINQ(无排序和有排序)
  • 测试用例 4:带有 C# 的经典(for(...)循环if(...)sort(...))(没有和有排序)

并且测试用例将在两个不同的环境中执行......

在Win10中测试

第一个测试环境是配备 i7-5600U @ 2.6GHz、Windows 10 x64、.NET 4.7.2 和 16GB 内存的 Lenovo T550。

C++ 测试结果如下:

C#测试结果如下:

在 openSUSE 上测试

第二个测试环境是联想 T520,配备 i5-2540M @ 2.6GHz、openSUSE Leap 15.4 x64、.NET 6.0 和 12 GB 内存。

C++ 测试结果如下:

C#测试结果如下:

结果比较

为了更好地比较结果,我忽略了最差的测试运行(最长的运行时间)并取其余三个测试运行的中值。这是这张摘要图片:

线系统硬件试图订购中位数C++ 与 C#LINQ 与经典
1赢得 10T550C++LINQ23.1 毫秒77 %worse差 2.5 倍
2赢得 10T550C#LINQ13.0 毫秒好 77 %
3赢得 10T550C++经典的9.2 毫秒73 %worse约好 2.5 倍
4赢得 10T550C#经典的5.3 毫秒好 73 %
5赢得 10T550C++LINQ是的19.0 毫秒好 186 %不一致的
6赢得 10T550C#LINQ是的54.3 毫秒差 186 %
7赢得 10T550C++经典的是的7.6 毫秒1309 % 更好不一致的
8赢得 10T550C#经典的是的107.1 毫秒差 1309 %
9openSUSET520C++LINQ11.5 毫秒好 60 %~ 3 倍差
10openSUSET520C#LINQ18.4 毫秒差 60%
11openSUSET520C++经典的5.1 毫秒平等的〜3倍好
12openSUSET520C#经典的5.1 毫秒平等的
13openSUSET520C++LINQ是的10.5 毫秒好 395 %不一致的
14openSUSET520C#LINQ是的52.0 毫秒差 395 %
15openSUSET520C++经典的是的5.1 毫秒23169 % 更好不一致的
16openSUSET520C#经典的是的123.4 毫秒差 23169 %

预期和结果的讨论

C++ 与 C#

  • 我期望 C++ 比 C# 有明显的优势。
  • 期望达到了。但是,并没有预期的那么一致。

除了第 1/2 行和第 3/4 行的突破之外,C++ 比 C# 更快——但并不显着。但是,只有通过排序,差异才会变得非常明显。显然,STL 和 C++ 编译器优化器在这里做得很好。这在第 7/8 行和第 15/16 行变得非常清楚——以一种几乎令人难以置信的方式。但是我已经重复了几次测试运行 - 结果没有显着变化。C# 总是失败。

LINQ 与经典(for(...) 循环、 if(...) 和 sort(...)

  • 我希望 LINQ 与经典方法相比有明显的劣势。
  • 期望达到了。然而,并没有想象中那么清晰。

对于 C++ 和 C# , LINQ 总是比经典方法(for(...)循环if(...)和)更糟糕。sort(...)但差异小于预期。

我认为 LINQ 在 C++ 中表现如此出色的原因是它是一个模板实现,可以转换为高度优化的机器代码。

我认为 LINQ 在 C# 中表现如此出色的原因是特殊的数据结构。C++ 中的 LINQvector<Element>用于源数据和结果,而 C# 中的 LINQList<Element>用于源数据和System.Linq.Enumerable.WhereListIterator<Element>/或System.Linq.OrderedEnumerable<Element, int>结果。第二个datatype 提供了对排序标准的明确访问,也可以被视为不再具有可比性或作弊。但让我们温和一点。

Wind10 与 openSUSE

我不想进一步评论它,但测试似乎在 Linux 下在较弱的硬件上运行得更快。也许是因为 Microsoft Defender - 它总是在我的 Windows 机器上运行。

缩放

与 C++ 相比,C# 相当可接受的结果让我感到惊讶(我曾预计至少有 10 次方作为差异),也让我感到高兴(显然 15 年的发展确实对 C# 产生了积极影响)。

不过,我想确定 C# 真的那么强大。640000所以我简单地将数据量从到乘以 20 倍12800000

缩放后的 C++ 测试结果为:

缩放后的 C# 测试结果为:

这是这张摘要图片:

线系统硬件试图订购中位数C++ 与 C#LINQ 与经典
1openSUSET520C++LINQ258.9 毫秒30 %worse~ 差 2 倍
2openSUSET520C#LINQ199.8 毫秒好 30%
3openSUSET520C++经典的135.4 毫秒21 %worse~ 好 2 倍
4openSUSET520C#经典的111.9 毫秒好 21%
5openSUSET520C++LINQ是的250.9 毫秒好 261 %不一致的
6openSUSET520C#LINQ是的906.2 毫秒差 261%
7openSUSET520C++经典的是的135.1 毫秒3224 % 更好不一致的
8openSUSET520C#经典的是的4491.5 毫秒差 322

http://www.ppmy.cn/news/163136.html

相关文章

tp5 whereor

条件查询方法 where方法 可以使用where方法进行AND条件查询&#xff1a; Db::table(think_user) ->where(name,like,%thinkphp) ->where(status,1) ->find(); 多字段相同条件的AND查询可以简化为如下方式&#xff1a; Db::table(think_user) ->…

520

好无聊啊 啊

安装deepin配置dtk开发环境

1.安装deepin系统 首先下载最新的deepin镜像&#xff0c;然后使用ventoy工具制作U盘启动。遗憾的是我的thinkpad t520 没法进入到安装界面。最终找到一个可以的版本。 2.升级deepin系统 安装完成后&#xff0c;最好升级到最新版本。不然有一些奇怪的问题。 3.配置dtk环境 …

20230109测试ToyBrick的RK3588开发板运行Buildroot的V0.02版本(20220312)

20230109测试ToyBrick的RK3588开发板运行Buildroot的V0.02版本&#xff08;20220312&#xff09; 2023/1/9 18:03 https://wiki.t-firefly.com/zh_CN/Firefly-Linux-Guide/manual_buildroot.html 1. Buildroot 使用手册 1.1. 桌面应用 官方发布的 Buildroot 固件&#xff0c;默…

[指导]Lenovo ThinkPad T420/T520/X220clover安装引导黑苹果

原文链接:http://www.insanelymac.com/forum/topic/285678-lenovo-thinkpad-t420-with-uefi-only/ 原文作者:tluck 一、准备工作: 1.下载efi文件用于USB启动盘引导安装,下载带clover引导的镜像,用transmac或者是RAW copy tool 工具写入U盘,替换clover引导文件。 …

520不敢说出口?教你硬核表白

完整项目已经放到github上&#xff0c;可以随意下载并直接运行&#xff0c;只求点个星github链接 临近5月20的时候&#xff0c;想起之前做过一个用程序做出一个爱心的图案&#xff0c;便突发奇想给它升级一下 爱心1.0 爱心2.0 目录 原理实现要点完整代码爱心1.0爱心2.0 总结…

鼎捷T100 Linux基础篇

文章目录 一、基本使用1.1 登入、登出系统1.2 变更密码 二、环境变量三、档案系统3.1 档案3.2 目录3.3 正则表达式3.4 文件系统管理指令3.4.1 显示文件列表3.4.2 新增、变更文件及目录3.4.3 复制、删除文件及目录3.4.4 切换工作目录及连结文件3.4.5 显示硬盘占用信息 3.5 文件权…

HP T520 和 T620 灵动系列瘦客户机电脑 - 在 Kiosk 模式下,使用 HP Easy Shell 后,应用无法启动...

说明 在 Kiosk 模式下&#xff0c;使用 HP Easy Shell 后&#xff0c;连接 RD Web 发布应用后&#xff0c;应用将无法启动。 启动应用后&#xff0c;连接停止响应。 症状&#xff1a; 选中已发布的应用后&#xff0c;该应用从不启动。 范围 本文档中的信息适用于以下&#xff1…