¿Por qué Entity Framework funciona más rápido que Dapper en la declaración de selección directa?

c# dapper entity-framework

Pregunta

Soy nuevo en el uso de ORM para tratar con la base de datos, actualmente estoy haciendo un nuevo proyecto y tengo que decidir si usaré Entity Framework o Dapper. Leí muchos artículos que dicen que Dapper es más rápido que Entity Framework.

Así que hice 2 proyectos prototipos simples, uno usando Dapper y el otro Entity Framework con una función para obtener todas las filas de una tabla. El esquema de la tabla como la siguiente imagen.

Esquema de tabla

y el código para ambos proyectos como el siguiente

para el proyecto 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());

para Entity Framework Project

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

después de probar el código anterior muchas veces, solo la primera vez que ejecuto el proyecto, el código dapper será más rápido y, después de esta primera vez, siempre obtengo mejores resultados del proyecto del marco de la entidad. También intenté la siguiente declaración sobre el proyecto del marco de la entidad para detener al perezoso. cargando

hrctx.Configuration.LazyLoadingEnabled = false;

pero sigue siendo el mismo EF realiza más rápido, excepto por primera vez.

¿Puede alguien darme una explicación u orientación sobre qué hace que EF sea más rápido en esta muestra, aunque todos los artículos en la web dicen lo contrario?

Actualizar

He cambiado la línea de código en el ejemplo de entidad para ser

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

El uso de AsNoTracking como se menciona en algunos artículos detiene el almacenamiento en caché de la estructura de la entidad y, después de detener el almacenamiento en caché, el ejemplo Dapper se está desempeñando mejor (pero no es una gran diferencia)

Respuesta popular

ORM (Object Relational Mapper) es una herramienta que crea una capa entre su aplicación y la fuente de datos y le devuelve los objetos relacionales en lugar de (en términos de c # que está utilizando) objetos ADO.NET. Esto es lo básico que hace cada ORM.

Para hacer esto, los ORM generalmente ejecutan la consulta y asignan el DataReader devuelto a la clase POCO. Dapper se limita hasta aquí.

Para ampliar esto aún más, algunos ORM (también llamados "ORM completo") hacen muchas más cosas como generar consultas para que su base de datos de aplicaciones sea independiente, almacenar en caché sus datos para futuras llamadas, administrar la unidad de trabajo para usted y mucho más. Todas estas son buenas herramientas y agregan valor a ORM; Pero viene con costo. Entity Framework cae en esta clase.

Para generar la consulta, EF tiene que ejecutar código adicional. La memoria caché mejora el rendimiento, pero la administración de la memoria caché necesita ejecutar código adicional. Lo mismo es cierto para la unidad de trabajo y cualquier otra característica adicional proporcionada por EF. Todo esto le ahorra escribir código adicional y EF paga el costo.

Y el costo es el rendimiento. Como Dapper hace un trabajo muy básico, es más rápido; Pero tienes que escribir más código. Como EF hace mucho más que eso, es (un poco) más lento; Pero tienes que escribir menos código.

Entonces, ¿por qué sus pruebas muestran resultados opuestos?
Porque las pruebas que está ejecutando no son comparables.

Los ORM completos tienen muchas características buenas como se explicó anteriormente; Uno de ellos es UnitOfWork. El seguimiento es una de las responsabilidades de UoW. Cuando se solicita el objeto (consulta SQL) por primera vez, provoca un viaje de ida y vuelta a la base de datos. Este objeto se guarda en la memoria caché. El ORM completo realiza un seguimiento de los cambios realizados en este objeto (s) ya cargados. Si se vuelve a solicitar el mismo objeto (otra consulta SQL en el mismo ámbito de UoW que incluye el objeto cargado), no realizan el viaje de ida y vuelta de la base de datos. En su lugar, devuelven el objeto de la memoria caché en su lugar. De esta manera, se ahorra un tiempo considerable.
Dapper no admite esta función que hace que se realice más lento en sus pruebas.

Pero, este beneficio solo es aplicable si el mismo objeto (s) se carga varias veces. Además, si el número de objetos cargados en la memoria es demasiado alto, esto ralentizará el ORM completo, ya que el tiempo requerido para verificar los objetos en la memoria será mayor. Así que de nuevo, este beneficio depende del caso de uso.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué