Günümüz yazılım dünyasında performans optimizasyonu büyük bir önem taşımaktadır. Özellikle büyük ve karmaşık uygulamalarda, gereksiz bellek tüketimini önlemek ve işlem süresini azaltmak için lazy loading (tembel yükleme) tekniği sıkça kullanılır.
Lazy loading, bir nesnenin veya verinin yalnızca ihtiyaç duyulduğunda yüklenmesini sağlayan bir tasarım prensibidir. Bu makalede lazy loading’in ne olduğu, nasıl çalıştığı, C# programlama dilinde nasıl kullanıldığı ve gerçek dünya senaryolarında nasıl uygulandığı ele alacağız.
Lazy Loading Nedir?
Lazy loading, bir nesnenin veya verinin, program çalıştığında hemen oluşturulmak yerine, yalnızca ona erişildiğinde oluşturulmasını sağlayan bir tekniktir. Bu teknik, özellikle şu durumlarda kullanışlıdır:
- Büyük veri kümeleri ile çalışırken belleği gereksiz yere doldurmamak.
- Ağ bağlantısı gerektiren işlemleri (veritabanı sorguları, API çağrıları) yalnızca gerektiğinde gerçekleştirmek.
- İlk yükleme süresini azaltmak, böylece uygulamanın daha hızlı açılmasını sağlamak.
Lazy loading, özellikle web uygulamalarında, veritabanı işlemlerinde, grafik yüklemelerinde ve nesne yönelimli programlamada (OOP) sıkça kullanılır.
Lazy Loading Nasıl Çalışır?
Lazy loading’in temel çalışma prensibi, nesneyi veya veriyi ilk başta oluşturmamak, sadece gerektiğinde yüklemektir. Bir nesneyi veya veriyi lazy loading ile yüklemek için şu adımlar izlenir:
- Nesne başlangıçta tanımlanır ancak oluşturulmaz.
- İlk erişimde nesne oluşturulur.
- Nesne oluşturulduktan sonra tekrar kullanılabilir ve aynı işlem tekrar yapılmaz.
Bu yaklaşım, özellikle performans gereksinimleri yüksek olan uygulamalarda büyük avantaj sağlar.
C# ile Lazy Loading Kullanımı
C# dilinde lazy loading’i uygulamanın birkaç yolu vardır:
Lazy<T> Sınıfı ile Lazy Loading
C#’ta lazy loading işlemi için Lazy<T> sınıfı kullanılabilir. Bu sınıf, .NET Framework ve .NET Core içinde hazır olarak gelir ve nesneleri yalnızca gerektiğinde oluşturur.
class Program
{
static void Main()
{
Lazy<VeritabaniBaglanti> baglanti = new Lazy<VeritabaniBaglanti>();
Console.WriteLine("Bağlantı nesnesi henüz oluşturulmadı.");
// Nesneye ilk erişim
VeritabaniBaglanti veri = baglanti.Value;
Console.WriteLine("Bağlantı nesnesi oluşturuldu ve kullanılıyor.");
}
}
class VeritabaniBaglanti
{
public VeritabaniBaglanti()
{
Console.WriteLine("Veritabanı bağlantısı kuruldu!");
}
}
Çıktı:
Bağlantı nesnesi henüz oluşturulmadı.
Veritabanı bağlantısı kuruldu!
Bağlantı nesnesi oluşturuldu ve kullanılıyor.
Bu örnekte, Lazy<T> kullanarak VeritabaniBaglanti nesnesini yalnızca ilk erişildiğinde oluşturduk.
Lazy<T> ile Thread Safety (Çoklu İş Parçacığı Güvenliği)
Lazy<T> varsayılan olarak thread-safe’dir. Yani, birden fazla iş parçacığı (thread) aynı anda Lazy<T> nesnesine erişmeye çalıştığında, nesne yalnızca bir kez oluşturulur ve tüm thread’ler bu nesneyi paylaşır.
Ancak, thread güvenliğini özelleştirmek için LazyThreadSafetyMode
kullanabilirsin.
class Program
{
static Lazy<VeritabaniBaglanti> baglanti =
new Lazy<VeritabaniBaglanti>(() => new VeritabaniBaglanti(),
LazyThreadSafetyMode.ExecutionAndPublication);
static void Main()
{
Parallel.Invoke(Erisim1, Erisim2);
}
static void Erisim1()
{
Console.WriteLine("Erişim 1 başladı.");
var nesne = baglanti.Value;
}
static void Erisim2()
{
Console.WriteLine("Erişim 2 başladı.");
var nesne = baglanti.Value;
}
}
class VeritabaniBaglanti
{
public VeritabaniBaglanti()
{
Console.WriteLine("Veritabanı bağlantısı oluşturuldu!");
}
}
Çıktı:
Erişim 1 başladı.
Erişim 2 başladı.
Veritabanı bağlantısı oluşturuldu!
Gördüğün gibi, Lazy<T> nesnesi sadece bir kere oluşturuluyor.
LazyThreadSafetyMode Seçenekleri:
- ExecutionAndPublication (Varsayılan): İlk thread nesneyi oluşturur ve diğerleri aynı nesneyi paylaşır.
- PublicationOnly: Birden fazla thread aynı anda yeni nesne oluşturabilir ama yalnızca biri kullanılır.
- None: Thread-safe değildir. Her thread kendi nesnesini oluşturabilir.