Łączę się z EF Core do istniejącej bazy danych stworzonej przy podejsciu code first z starego EF i porównuje czasy i widze, ze EF Core czasy wychodza wieksze niz w przypadku starego EF?
Czy powodem może być to, że do bazy podłączam się istniejącej i to wina bardziej z poziomu kodu niz softwaru?
Benchmarks or didn't happen. Mam wrażenie, że Twoje metody badawcze są bezwartościowe.
Podejrzałem i oba EF generują takie samo zapytanie ... jednego zwykłe złączenie wewnetrzne
(sorki za post pod postem)
Zauważyłem że nawet dla pobrania 10 rekordów z bazy średni czas ef core oscyluje mi w 100-150 ms natomiast EF6 zajmuje to z kolei ~50ms.
Czy to przez to, że EF Core łącze się już do istniejącej bazy?
Co robi? że niby utworzenie bazy przez EF/C miało wpływ na wydajność?
Wątpliwe. Powiedz coś o swoim środowisku - jaka baza, na czym stoi? windows linux docker? tracking on/off?
Windows, SQL Server standard. Śledzenie obiektów wyłączone
A jak wygląda kod? Rozgrzewasz go? Robisz wiele powtórzeń i liczysz średnią?
Kilkanaście razy pusciłem i widziałem ze oscylowalo w tych samych przedziałach. Nie nie licze średniej
Poniższy kod zamknięty pomiędzy obiektem klasy StopWatch, a StopWatch.Elapsed
var data = _context.Tabela1
.Join(_context.Tabela2,
x => x.Id,
e => e.Tabela1Id,
(obiekt1, obiekt2) => new ViewModel
{
Id = obiekt1.Id
Id2 = obiekt2.Id
Dane = obiekt2.Dane
})
.Take(count)
.AsNoTracking()
.ToList()
Benchmark słaby, ale wyszło mi, że jeżeli obie aplikacje nie są odpalone w tym samym momencie, to ich wyniki są porównywalne.
gdy odpalimy obie, to EF wygrywa :D
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF
{
class Program
{
static void Main(string[] args)
{
var context = new Context();
var sw = new Stopwatch();
while (true)
{
sw.Start();
var data = context.Books.ToList();
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Reset();
}
}
}
public class Context : DbContext
{
public Context() : base("SQLExpress")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Book> Books { get; set; }
}
public class User
{
public User()
{
}
public User(string firstName)
{
FirstName = firstName;
}
public Guid Id { get; set; } = Guid.NewGuid();
public string FirstName { get; set; }
public List<Book> Books { get; set; } = new List<Book>();
}
public class Book
{
public Book()
{
}
public Book(string title)
{
Title = title;
}
public Guid Id { get; set; } = Guid.NewGuid();
public Guid UserId { get; set; }
public string Title { get; set; }
}
}
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace EFCore
{
class Program
{
static void Main(string[] args)
{
var context = new Context();
context.Database.EnsureCreated();
Seeder(context);
var sw = new Stopwatch();
while (true)
{
sw.Start();
var data = context.Books.ToList();
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Reset();
}
}
private static void Seeder(Context context)
{
if (!context.Users.Any())
{
for (int i = 0; i < 1000; i++)
{
var books = new List<Book>();
for (int y = 0; y < 50; y++)
{
books.Add(new Book($"{i}_{y}"));
}
var user = new User(i.ToString());
user.Books.AddRange(books);
context.Add(user);
}
context.SaveChanges();
}
}
}
public class Context : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer("SQLExpress");
}
public DbSet<User> Users { get; set; }
public DbSet<Book> Books { get; set; }
}
public class User
{
public User()
{
}
public User(string firstName)
{
FirstName = firstName;
}
public Guid Id { get; set; } = Guid.NewGuid();
public string FirstName { get; set; }
public List<Book> Books { get; set; } = new List<Book>();
}
public class Book
{
public Book()
{
}
public Book(string title)
{
Title = title;
}
public Guid Id { get; set; } = Guid.NewGuid();
public Guid UserId { get; set; }
public string Title { get; set; }
}
}
Czy to możliwe, że RemoveRange w efcorze dla np 100 elementow dziala szybciej niz w EF6? bo takie cuda mi wychodza ;d
A czemu miałoby nie być? :)
Dlatego że gdy porównuje EF Core z EF6 zapytania składające się z joinów i selecta to wychodzi, ze EF 6 jest szybszy. Natomiast podczas multiple remove wychodzi, ze EF Core jest szybszy** kilka razy **od EF6. Dlatego w to gdybam ;s
Nie ma żadnej reguły, że jeśli coś jest szybsze w jednym przypadku, to jest też szybsze od innych. Wręcz przeciwnie, od przypadków zależy wszystko. Dlatego bardzo trudno jest zrobić dobrze oddającego rzeczywistość benchmarka. Np. tutaj https://github.com/DevExpress/XPO/blob/master/Benchmarks/README.md#deletemany-method poniżej 100 obiektów Core miewa przewagę, a powyżej tego zaczyna zostawać z tyłu. Żeby wyciągnąć z tego użyteczne wnioski to trzeba znać konkretny przypadek zastosowania.
Chłopie, zanim zabierzesz się za testy wydajnościowe albo porównanie wydajności jakichś technologii warto byłoby, żebyś chociaż poznał podstawowe różnice pomiędzy nimi, bo teraz strzelasz na oślep i w większości przypadków nie rozumiesz co się dzieje i dlaczego. Tym sposobem nie dojdziesz do żadnych sensownych wniosków.
Tutaj może być jeden z powodów dlaczego operacje na wielu obiektach na raz mogą być szybsze w EF Core niż w EF - https://www.talkingdotnet.com/what-is-batching-of-statement-in-entity-framework-core/
Ale takich niuansów i różnic pewnie znajdzie się więcej.