Blazor i .NET

EF6 ili EF Core 10: iste upite pokrenuli smo na oba i izmjerili razliku

EF6 ili EF Core? Izmjerili smo EF6 na .NET Frameworku i .NET-u 10 protiv EF Core 10 na SQL Serveru: čitanje, unos, izmjene. EF Core je do 17 puta brži.

Vlado Pandžić

Vlado Pandžić · Osnivač · Senior .NET arhitekt
Objavljeno · 9 min čitanja

Sadržaj
  1. Kako smo mjerili
  2. Rezultati
  3. Spremanje podataka: tu je razlika najveća
  4. Čitanje podataka: stalni napredak i jedno iznenađenje
  5. EF6 na .NET-u 10: koristan međukorak
  6. Što to znači u praksi
  7. Pitanja koja najčešće čujemo
  8. Kako mi radimo

„Je li EF Core stvarno brži ili to samo piše u release notesima?” To pitanje postavi svaki tim sa starom aplikacijom na Entity Frameworku 6 prije nego što odluči isplati li se migracija. Microsoft objavljuje benchmarke, ali oni rijetko izgledaju kao upiti u stvarnom sustavu za narudžbe ili fakturiranje.

Zato smo napisali upite kakve takav sustav zaista sadrži i pokrenuli potpuno iste na tri postava: EF6 na .NET Frameworku 4.8, gdje živi većina EF6 aplikacija, EF6 na .NET-u 10, što je moguće od verzije EF 6.4, i EF Core 10 na .NET-u 10. Ista baza, isti podaci, iste klase entiteta.

Kratki odgovor: EF Core 10 bio je 1,6 do 17 puta brži od EF6 na .NET Frameworku i trošio je do 28 puta manje memorije. Najveća razlika nije bila u čitanju, nego u spremanju podataka. A EF6 na .NET-u 10 pokazao se kao koristan međukorak: brži nego na .NET Frameworku, bez diranja ijednog upita.

Kako smo mjerili

  • Baza: SQL Server (LocalDB) na istom računalu, s 1.000 kupaca, 10.000 narudžbi s poljem za napomene od 2 KB i 50.000 stavki narudžbi. Četvrtina narudžbi je otvorena.
  • Iste klase entiteta za sva tri postava, mapirane na iste tablice. EF6 6.5.1 i EF Core 10.
  • Alat: BenchmarkDotNet 0.15.8, s 3 iteracije zagrijavanja i 12 mjerenih po slučaju, uz bilježenje alokacija memorije.
  • Svaki slučaj otvara novi kontekst, kao što bi to napravio web zahtjev. Unosi i izmjene rade se u transakciji koja se poništava, pa svaka iteracija vidi iste podatke.
  • Računalo: laptop s procesorom Intel Core Ultra 7 255H.

Sedam operacija:

Operacija Što predstavlja
100 dohvata po id-u, jedan po jedan Učitavanje zapisa jedan po jedan na ekranu ili u importu
Učitavanje 2.500 otvorenih narudžbi, bez praćenja Lista ili izvještaj samo za čitanje
Učitavanje 2.500 otvorenih narudžbi, s praćenjem Ista lista, onako kako je učitava većina starijeg koda
Projekcija otvorenih narudžbi u malu klasu Ekran s listom napravljen kako treba
Učitavanje 100 narudžbi sa stavkama (Include) Detalji narudžbe ili izvoz
Unos 500 narudžbi Import ili batch posao
Učitavanje i izmjena 200 narudžbi Masovna promjena cijena

Rezultati

Koliko je puta EF Core 10 na .NET-u 10 bio brži od EF6 na .NET Frameworku 4.8

Operacija EF6, .NET Framework 4.8 EF6, .NET 10 EF Core 10 EF Core 10 naspram EF6 na 4.8
100 dohvata po id-u 30,2 ms 17,1 ms 8,0 ms 3,8× brže
2.500 narudžbi, bez praćenja 58,3 ms 44,0 ms 24,4 ms 2,4× brže
2.500 narudžbi, s praćenjem 87,6 ms 59,3 ms 40,5 ms 2,2× brže
Projekcija u malu klasu 9,0 ms 5,5 ms 5,8 ms 1,6× brže
100 narudžbi sa stavkama 17,4 ms 13,6 ms 11,1 ms 1,6× brže
Unos 500 narudžbi 272,0 ms 127,7 ms 15,9 ms 17× brže
Izmjena 200 narudžbi 22,4 ms 18,7 ms 6,6 ms 3,4× brže

Memorija se kretala u istom smjeru, a ponegdje i puno dalje:

Operacija EF6, .NET Framework 4.8 EF Core 10
100 dohvata po id-u 7,1 MB 1,6 MB
2.500 narudžbi, bez praćenja 31,2 MB 10,8 MB
2.500 narudžbi, s praćenjem 37,3 MB 13,2 MB
Unos 500 narudžbi 153,6 MB 5,4 MB
Izmjena 200 narudžbi 8,6 MB 2,5 MB

Jedna iskrena napomena: rezultati unosa za EF6 razlikovali su se od pokretanja do pokretanja, otprilike od 250 do 330 ms na .NET Frameworku. Tablica prikazuje zadnje pokretanje. Razlika prema EF Coreu bila je veća od 15 puta u svakom pokretanju.

Spremanje podataka: tu je razlika najveća

Unos je najupečatljiviji broj i vrijedi ga razumjeti, jer upravo tu mnoge EF6 aplikacije gube najviše vremena u importima i noćnim poslovima.

for (var i = 0; i < 500; i++)
    db.Orders.Add(new Order { CustomerId = 1, Date = DateTime.Today, Total = 10m, Status = "New" });
db.SaveChanges();

Isti kod na oba. Dvije stvari ovdje usporavaju EF6:

  • EF6 šalje jedan INSERT po retku. 500 narudžbi znači 500 zasebnih naredbi prema bazi. EF Core ih grupira u nekoliko batch naredbi. Na stvarnom serveru preko mreže svaki od tih 500 odlazaka i povrataka dodaje kašnjenje, pa razlika samo raste.
  • EF6 pri svakom Add provjerava sve praćene entitete. Svaki poziv pokreće detekciju promjena nad svime što je već u kontekstu, pa dodavanje mnogo entiteta postaje sve sporije što ih je više.

Za drugi problem postoji jeftin lijek u samom EF6 i vrijedi ga znati čak i ako nikad ne migrirate:

db.Orders.AddRange(orders);
db.SaveChanges();

S AddRange isti je unos u EF6 na .NET Frameworku trajao 80,9 ms umjesto 272 ms i alocirao 21 MB umjesto 154 MB. I dalje pet puta sporije od EF Corea, jer jedan INSERT po retku ostaje, ali to je 3× brže uz promjenu jedne linije. Ako vaša EF6 aplikacija ima import koji dodaje retke u petlji, krenite odatle.

Izmjene slijede isti obrazac. EF Core šalje 200 izmjena u batchevima, a njegov change tracker radi manje posla po entitetu, što se vidi kao 3,4 puta veća brzina i trećina memorije.

Čitanje podataka: stalni napredak i jedno iznenađenje

Kod čitanja je EF Core 10 bio 1,6 do 3,8 puta brži. Najveći dobitak bio je kod mnogo malih upita: 100 dohvata po id-u trajalo je 30 ms na EF6 i 8 ms na EF Coreu. Svaki upit u EF Coreu ima puno manje troška oko prevođenja i izvršavanja, što je važno u kodu koji pokreće mnogo malih upita, recimo na ekranima koji povezane podatke učitavaju zapis po zapis.

Iznenađenje je bila projekcija. Kad upit odabere samo stupce koji ekranu trebaju, EF6 na .NET-u 10 bio je jednako brz kao EF Core 10: 5,5 ms naspram 5,8 ms. Većina posla tu se odvija u bazi, a oba joj šalju sličan SQL upit. Projekcija je dobar savjet na bilo kojoj verziji, kao što je pokazao i naš članak o pet najčešćih grešaka s EF Coreom.

EF6 na .NET-u 10: koristan međukorak

Mnogi timovi migraciju zamišljaju kao jedan veliki korak: s .NET Frameworka i EF6 na .NET 10 i EF Core. Ne mora biti tako. EF6 radi na modernom .NET-u od verzije 6.4, a u našim mjerenjima samo njegovo prebacivanje na .NET 10 učinilo ga je 1,2 do 2,1 puta bržim, bez promjene ijednog upita.

To otvara put u dva koraka:

  1. Korak 1Prebacite aplikaciju na .NET 10, EF6 ostaje
  2. Korak 2Zamijenite EF6 EF Coreom, dio po dio

Prvi korak donosi podržan runtime i dio brzine. Drugi se onda može odvijati postupno, počevši od dijelova koji spremaju najviše podataka ili pokreću najviše upita. EF6 na modernom .NET-u treba konfiguraciju u kodu umjesto u app.config, što je nekoliko linija:

public class Ef6Configuration : DbConfiguration
{
    public Ef6Configuration()
    {
        SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);
        SetProviderFactory(SqlProviderServices.ProviderInvariantName, SqlClientFactory.Instance);
    }
}

Postoje i ograničenja: EF6 dizajner ne radi izravno u modernim .NET projektima, pa modeli izrađeni iz EDMX datoteka traže dodatni posao, a EF6 je stabilan i podržan, ali se više aktivno ne razvija. To je most, a ne odredište. Cijeli prelazak, i što ga otežava ili olakšava, opisali smo u članku o migraciji s EF6 na EF Core.

Što to znači u praksi

Nekoliko milisekundi po upitu zvuči malo. Ali zbraja se upravo tamo gdje tvrtka to stvarno osjeti:

  • Importi i noćni poslovi. Import od 50.000 redaka koji unosi u petlji mjesto je gdje se onih 17× vidi kao sati koji postaju minute.
  • Opterećeni ekrani. Ekran koji pri svakom učitavanju pokrene 100 malih upita brži je za 22 ms po korisniku, svaki put, a server odradi četvrtinu posla s alokacijama.
  • Troškovi servera. Manje memorije po zahtjevu znači manje garbage collectiona i više zahtjeva po serveru, što je važno kad plaćate svaku instancu u Azureu.

U jednom su smislu ovi brojevi donja granica: baza je radila na istom računalu, pa mreže nije bilo. Na stvarnom SQL Serveru ili Azure SQL-u svaki odlazak do baze koji EF6 napravi, a EF Core izbjegne, košta i mrežno kašnjenje.

Koliko običan poslovni kod radi brže na .NET-u 10 nego na .NET Frameworku, bez ikakve baze, pokazali smo u mjerenju .NET Framework 4.8 ili .NET 10.

Pitanja koja najčešće čujemo

Isplati li se migrirati s EF6 na EF Core samo zbog brzine?

Samo zbog brzine obično ne. Ali brzina je rijetko jedini razlog: EF6 više ne dobiva nove mogućnosti i mnoge aplikacije veže uz .NET Framework. Ako ionako prelazite na .NET 10, podatkovni sloj trebao bi završiti na EF Coreu. Počnite s dijelovima koji spremaju najviše podataka.

Možemo li jednostavno pokrenuti EF6 na .NET-u 10?

Da, od verzije EF 6.4. Aplikacije čiji je model izrađen u EF6 dizajneru iz EDMX datoteke prvo traže nešto dodatnog posla. U našim mjerenjima bio je 1,2 do 2,1 puta brži nego na .NET Frameworku. To je dobar prvi korak, ali ne i dugoročno rješenje.

Vrijede li ovi rezultati i na stvarnom SQL Serveru?

Smjer vrijedi. Točne milisekunde ovise o vašem serveru, podacima i indeksima. Kod unosa i izmjena razlika preko mreže postaje još veća, jer EF6 radi puno više odlazaka do baze. Zato se isplati izmjeriti vlastite najsporije operacije prije i poslije.

Naš EF6 import je spor. Što najbrže pomaže?

Zamijenite Add u petlji jednim AddRange ili isključite automatsku detekciju promjena tijekom importa. U našem testu samo je to EF6 unos ubrzalo tri puta.

Kako mi radimo

Upravo ovo radimo. ProCoding je .NET studio iz Splita i prebacujemo .NET Framework aplikacije i njihove EF6 podatkovne slojeve na .NET 10 i EF Core: prvo mjerimo, migriramo u koracima koje poslovanje ne primijeti i svaki korak provjeravamo brojkama. Samostalno, s vašim timom ili kao freelance .NET developer unutar vašeg tima. Prvi korak je besplatan razgovor od 30 minuta.

Izvori

Ovaj članak služi općem informiranju i nije pravni, porezni, financijski ni drugi stručni savjet. Scenariji, primjeri i izračuni su ilustrativni. Uvjeti korištenja i odricanje od odgovornosti.

Povezani članci

© 2026 ProCoding — Sva prava pridržana.Impresum i privatnostUvjeti korištenjaSplit, Hrvatska