LINQ: Lazy Evaluation ve Performans Üzerindeki Etkisi¶
LINQ’da sorguların nasıl çalıştığını anlamak, hem performansı optimize etmek hem de beklenmeyen sonuçların önüne geçmek için kritiktir. LINQ sorguları, varsayılan olarak “lazy evaluation” (ertelemeli değerlendirme) prensibiyle çalışır.
1. Lazy Evaluation Nedir?¶
Lazy evaluation, bir LINQ sorgusunun ancak sonucun talep edilmesi durumunda çalıştırılmasıdır. Bu, sorgu zincirlerinin gereksiz yere çalıştırılmasını engeller ve bellek kullanımını azaltır.
Örnek:
var query = numbers.Where(n => n > 10);
// Sorgu burada çalıştırılmaz, yalnızca tanımlanır.
foreach (var number in query)
{
Console.WriteLine(number);
}
// Sorgu burada çalıştırılır.
Bu örnekte, query
tanımlanır ancak yalnızca döngü çalıştırıldığında veritabanına sorgu gönderilir.
2. Yanlış ve İdeal Kullanım¶
Yanlış Kullanım: Gereksiz işlem zincirleri oluşturmak¶
❌ Yanlış Kullanım:
var query = numbers.Where(n => n > 10).OrderBy(n => n).Skip(5);
// Sorgu gereksiz yere zincirlenir ve performansı etkiler
var result = query.ToList();
Her bir adım, gereksiz işlemleri zincirleyerek veritabanında ağır bir sorguya dönüşebilir.
İdeal Kullanım: Yalnızca ihtiyaç duyulan işlemleri zincirlemek¶
✅ İdeal Kullanım:
var result = numbers
.Where(n => n > 10)
.OrderBy(n => n)
.Skip(5)
.Take(10)
.ToList();
Bu yaklaşım, yalnızca ihtiyaç duyulan veriyi işleyerek performansı artırır.
3. Immediate Execution¶
Eğer bir sorgunun hemen çalışmasını istiyorsanız, ToList()
, Count()
, veya First()
gibi metotlar kullanabilirsiniz.
✅ Örnek:
var result = numbers.Where(n => n > 10).ToList();
// Sorgu burada hemen çalıştırılır.
Immediate execution, özellikle sonuçların birden fazla kez kullanılacağı durumlarda faydalıdır.
4. Performans Tuzağı: Multiple Iteration¶
Bir LINQ sorgusu birden fazla kez iterasyona tabi tutulursa, her seferinde yeniden çalıştırılır.
❌ Yanlış Kullanım:
var query = numbers.Where(n => n > 10);
Console.WriteLine(query.Count()); // Sorgu çalışır
foreach (var number in query) // Sorgu tekrar çalışır
{
Console.WriteLine(number);
}
Bu yaklaşım, aynı sorgunun iki kez çalıştırılmasına neden olur.
✅ İdeal Kullanım:
var result = numbers.Where(n => n > 10).ToList();
Console.WriteLine(result.Count());
foreach (var number in result)
{
Console.WriteLine(number);
}
Bu yöntem, sorgunun yalnızca bir kez çalıştırılmasını sağlar.
5. Performans Testi¶
Lazy evaluation ile immediate execution arasındaki farkı ölçmek için:
✅ Örnek Performans Testi:
var stopwatch = Stopwatch.StartNew();
// Lazy Evaluation
var query = numbers.Where(n => n > 10);
stopwatch.Stop();
Console.WriteLine($"Lazy Evaluation Süresi: {stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
// Immediate Execution
var result = numbers.Where(n => n > 10).ToList();
stopwatch.Stop();
Console.WriteLine($"Immediate Execution Süresi: {stopwatch.ElapsedMilliseconds} ms");
6. Lazy Evaluation’un Avantajları ve Dezavantajları¶
Avantajlar | Dezavantajlar |
---|---|
Bellek kullanımını optimize eder | Çok sayıda tekrar eden iterasyon performansı düşürür |
Sorgular sadece ihtiyaç duyulduğunda çalışır | Karmaşık sorgu zincirleri ağır sorgular oluşturabilir |
Verinin tamamı yüklenmeden işlem yapılabilir | Sorguların beklenmeyen zamanlarda çalışmasına neden olabilir |