Jagged ve 2D dizilerde özel sıralama, LINQ ile karşılaştırmalı benchmark
Željko Perić, 2D ve jagged dizilerde çok sütunlu sıralama için yazdığı özel extension metodlarını BenchmarkDotNet ile LINQ OrderBy/ThenBy hattına karşı ölçtü. Sonuçlar, bellek düzeninin ve algoritmanın büyük veri setlerinde performansı nasıl etkilediğini somut sayılarla gösteriyor. Bellek tahsisi ve GC baskısı ile ilgilenen her .NET geliştiricisi için faydalı bir örnek.
Kilit noktalar
- Jagged dizi (T[][]) QuickSort'u satır referanslarını takas eder ve benchmark'ta sıfır heap tahsisi gösterdi.
- 1.000.000 satırda FastSort yaklaşık 1,41 saniye, LINQ ise yaklaşık 1,26 saniye sürdü; fark yaklaşık %13.
- LINQ yaklaşık 100 MB (100.002.168 bayt) tahsis ederken FastSort yalnızca 88 bayt tahsis etti.
- T[,] üzerindeki QuickSort, hücreleri tek tek taşıdığı için en yavaş ve en çok bellek kullanan varyant oldu.
- Sonuçları karşılaştırmadan önce BenchmarkDotNet'in MemoryDiagnoser çıktısındaki Ratio ve Allocated sütunlarına bakın.
Bu yazı, daha önce anlattığı iki boyutlu dizi sıralama extension'larının performansını LINQ ile karşılaştırıyor. Test, BenchmarkDotNet ve .NET 10 üzerinde, 10 sütunlu, hücre başına 1024 bayt yük taşıyan ve çok sayıda eşit değer içeren veri setleriyle 100'den 1.000.000 satıra kadar yapıldı. En büyük boyutta jagged dizi QuickSort'u ve IntroSort tabanlı FastSort, LINQ'e yakın süreler verirken çok az bellek tahsis etti. Buna karşılık T[,] dizisi üzerindeki QuickSort yaklaşık 3,4 kat yavaş kaldı ve yaklaşık 69 MB tahsis etti; çünkü satırlar yerine tek tek hücreler taşınıyor.
Yazar, LINQ'in büyük veride süresinin büyük kısmını tahsis ve GC baskısının belirlediğini vurguluyor. Ancak sonuçlar tek bir Windows 11 makinesinde ve sentetik veriyle alındığı için mutlak süreler değil oranlar üzerinden yorumlanmalı. Kodun GitHub'daki tam hali, kendi ortamınızda ölçüm yapmak için orijinal yazıda yer alıyor.
Gerçek dünyada kullanımı
- Yüz binlerce satırlık raporu bellek tahsisi olmadan çok sütunlu ASC/DESC kurallarla sıralaması gereken bir veri işleme servisi.
- Sık tekrar eden sıralama yapılan, GC duraklamalarından kaçınmak isteyen bir oyun veya simülasyon katmanı.
- Çok sütunlu sıralama mantığını LINQ yerine kendi kodunuzda kontrol etmek isteyen yüksek hacimli bir arka plan işçisi.
Neden önemli
LINQ çoğu durumda yeterli olsa da büyük verilerde ara tahsisler GC baskısını artırıyor. Jagged dizi ve struct comparer ile yazılmış bir sıralama, bu maliyeti ciddi ölçüde düşürebilir; ancak her zaman kendi ortamınızda BenchmarkDotNet ile ölçmeniz gerekir.