为什么 Entity Framework 在直接 select 语句中执行速度比 Dapper 快

2024-03-11

我是使用 ORM 处理数据库的新手,目前我正在制作一个新项目,我必须决定是使用 Entity Framework 还是 Dapper。我读过很多文章,都说 Dapper 比实体框架更快。

因此,我制作了 2 个简单的原型项目,一个使用 Dapper,另一个使用实体框架和一个函数来从一张表中获取所有行。 表架构如下图

两个项目的代码如下

对于 Dapper 项目

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Emp> emplist = cn.Query<Emp>(@"Select * From Employees");
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());

对于实体框架项目

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());

在多次尝试上述代码后,仅在第一次运行该项目时,简洁的代码会更快,并且在第一次之后,我总是从实体框架项目中获得更好的结果 我还在实体框架项目上尝试了以下语句来停止延迟加载

hrctx.Configuration.LazyLoadingEnabled = false;

但除了第一次之外,相同的 EF 仍然执行得更快。

尽管网络上的所有文章都说相反的内容,但任何人都可以给我解释或指导如何使 EF 在此示例中更快

Update

我已将实体示例中的代码行更改为

IEnumerable<Employee> emplist = hrctx.Employees.AsNoTracking().ToList();

使用不追踪正如一些文章中提到的,停止实体框架缓存,停止缓存后,dapper 示例的性能更好,(但差别不是很大)


ORM(对象关系映射器)是一种在应用程序和数据源之间创建层并返回关系对象而不是对象的工具。 (就您正在使用的 C# 而言)ADO.NET 对象。这是每个 ORM 所做的基本事情。

为此,ORM 通常会执行查询并map返回的DataReader到 POCO 类。 Dapper 仅限于此。

为了进一步扩展这一点,一些 ORM(也称为“完整 ORM”)可以做更多的事情,例如为您生成查询以使您的应用程序数据库独立、缓存您的数据以供将来调用、为您管理工作单元等等。所有这些都是很好的工具,为 ORM 增加了价值;但这是有代价的。实体框架属于此类。

为了生成查询,EF 必须执行额外的代码。缓存提高了性能,但管理缓存需要执行额外的代码。对于工作单元和 EF 提供的任何其他附加功能也是如此。这一切都节省了you编写额外的代码,EF 支付成本。

And the cost是性能。由于 Dapper 做了非常基本的工作,所以速度更快;但你必须编写更多代码。由于 EF 的作用远不止于此,因此它(有点)慢;但你必须编写更少的代码。

那么为什么你的测试显示相反的结果呢?
因为您正在执行的测试不具有可比性。

如上所述,完整的 ORM 有许多好的特性;其中之一是UnitOfWork。跟踪是 UoW 的职责之一。当第一次请求该对象(SQL 查询)时,会导致与数据库的往返。然后该对象被保存在内存缓存中。完整的 ORM 会跟踪对此已加载的对象所做的更改。如果再次请求相同的对象(同一 UoW 范围内包含已加载对象的其他 SQL 查询),它们不会进行数据库往返。相反,它们从内存缓存中返回对象。这样,可以节省大量时间。
Dapper 不支持此功能,这会导致它在测试中执行速度变慢。

但是,此优点仅适用于多次加载相同对象的情况。此外,如果内存中加​​载的对象数量太多,这会减慢整个 ORM 的速度,因为check内存中的对象会更高。同样,这种好处取决于用例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Entity Framework 在直接 select 语句中执行速度比 Dapper 快 的相关文章

  • 为什么在从同一解决方案引用另一个项目时会出现 FileNotFound 异常?

    我正在学习如何使用 NUnit 我的解决方案中有我的主项目 并在同一解决方案中创建了一个单独的项目 该项目将保存我的单元测试 并具有自己的命名空间 从该项目中 我添加对主项目的引用并添加 using MainProjectNamespace
  • 氧图。如何将轴旁边的值格式从 1000 更改为 1k

    我正在尝试更改轴旁边的值的格式 例如从 1000 更改为 1k 或 1000000 更改为 1M 这在 LinearAxis 中可能吗 这是我的代码 m Axes Add new LinearAxis Position AxisPositi
  • 委托和接口如何互换使用?

    我可以使用接口方法代替委托吗 如何 我发现搜索接口方法比使用委托更快 我希望有一个简单的代码片段 理论上 可以通过包含单个方法的接口 例如 Java 没有委托 来完成委托完成的所有工作 然而 它使代码变得更加冗长并且没有带来什么好处 话又说
  • 如何在 C# 中启动文件

    编辑 我觉得自己像个白痴 我有一种感觉 像下面的答案会起作用 但没有看到任何与下面的答案类似的谷歌结果 所以当我看到这段复杂的代码时 我想它一定是这样的 我搜索并找到了这个Windows 列出并启动与扩展关联的应用程序 https stac
  • 以概率从列表中选择随机元素

    我有一个包含四个项目 A B C D 的列表 每个项目都有被选择的概率 例如 A 有 74 的机会被选中 B 15 C 7 D 4 我想创建一个函数 根据其概率随机选择一个项目 有什么帮助吗 为您的项目定义一个类 如下所示 class It
  • lambda 表达式到函数指针的转换

    这是这个问题的后续问题 Lambda 如何作为参数传递 https stackoverflow com questions 3321283 c0x lambda how can i pass as a parameter 据推测 MSDN
  • 用C#发送USSD?

    我想编写一个在 Windows Mobile 6 上运行的简单 C 应用程序 它可以发送 USSD 消息 有没有任何图书馆可以帮助我做到这一点 或者是否有任何示例解释如何使用线路发送USSD http msdn microsoft com
  • File.ReadAllLines 或流读取器

    我们可以使用以下方式读取文件StreamReader http msdn microsoft com en us library vstudio system io streamreader或通过使用File ReadAllLines ht
  • 更新 OSX 命令行工具 6.3 后缺少 C++ 标头 <__debug>

    从 App Store 更新到 Command Line Tools 6 3 后 程序包括
  • 如何获取 C# PriorityQueue 元素的优先级

    我正在初始化一个存储 XY 坐标的优先级队列 根据距原点的欧几里得距离确定优先级 我创建了一个自定义Comparer这使得它作为最大堆运行 PriorityQueue
  • 公共领域有哪些替代方案?

    我正在用 java 编写一个游戏 正如问题标题建议的那样 我在类中使用公共字段 暂且 据我所知 公共领域很糟糕 我有一些理解其中的原因 但如果有人能澄清为什么你不应该使用它们 那将不胜感激 问题是 从我所看到的来看 这似乎是合乎逻辑的 是使
  • 泛型类上的 DebuggerDisplay

    我在应用时遇到问题DebuggerDisplay泛型类的属性 DebuggerDisplay foo class Foo DebuggerDisplay Bar t class Bar
  • dlopen 或 dlclose 未调用信号处理程序

    我在随机时间内收到分段错误 我注册了信号 但发生分段错误时未调用信号处理程序 include
  • 使用 MessagingCenter 和标准 .NET 事件处理程序向感兴趣的各方通知更改有什么区别?

    使用 MessagingCenter 和标准 NET 事件处理程序向感兴趣的各方通知更改有什么区别 下面演示了同一事物的两个 未经测试的 实现 public class FooClass public event EventHandler
  • 模板“内联”函数的静态局部变量[重复]

    这个问题在这里已经有答案了 static的局部变量inline如果我的理解是正确的 C 中的函数保证像单个全局变量一样存在 如果inline函数是一个模板 编译器可以在哪里生成该函数的多个版本 下面这篇文章应该很好地回答你的问题 http
  • C++头文件问题

    我在处理类时尝试了一些 C 代码 这个问题出现在我身上 并且让我有点烦恼 我创建了一个包含类定义的头文件和一个包含实现的 cpp 文件 如果我在不同的 cpp 文件中使用此类 为什么要包含头文件而不是包含类实现的 cpp 文件 如果我包含类
  • C++20 views::join 在生成的嵌套范围::single_view 上进入无限循环

    我正在使用 GCC 实现 v10 2 和 v11 来处理 C 20 范围 测试的行为std views join https en cppreference com w cpp ranges join view 我尝试使用生成嵌套视图sin
  • 为什么 C++ 元组如此奇怪?

    我通常创建自定义structs将不同类型的值分组在一起时 这通常很好 而且我个人发现命名成员访问更容易阅读 但我想创建一个更通用的 API 在其他语言中广泛使用元组后 我想返回类型的值std tuple但发现它们在 C 中使用比在其他语言中
  • 我的 Opencv 应用程序处理速度非常慢

    我正在构建一个 OpenCV 应用程序 它从相机捕获视频 并在删除背景后将其覆盖在另一个视频上 我无法达到合理的速度 因为它以大约 1 fps 的速度播放输出 而我的背景去除以 3 fps 的速度工作 有没有办法以正常速度显示背景视频并以
  • InvalidOperationException:没有为方案“CookieSettings”注册身份验证处理程序

    我正在使用 ASP Net MVC core 2 1 开发一个应用程序 其中不断出现以下异常 InvalidOperationException 没有为方案 CookieSettings 注册身份验证处理程序 注册的方案有 Identity

随机推荐