ProgramlamaiOS geliştirici

Swift'te lazy sequence nedir? Nasıl çalışır, ne zaman kullanılmalı ve hangi tuzaklar vardır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Lazy sequence, hesaplamaların (filter, map vb.) yapılmasını elemanlara doğrudan erişim anına kadar erteleyen bir koleksiyon sarmalayıcısıdır. Bu, lazy sequence üzerindeki işlemlerin yalnızca sonuçlarına erişildiğinde hesaplanacağı anlamına gelir (örneğin, .forEach, .first, diziye dönüştürme vb. çağrıldığında).

Ne zaman kullanılmalı:

  • Eğer tüm elemanları aynı anda işlemenin gereği yoksa, büyük dizilerle çalışırken.
  • Ardışık dönüşümlerde (map -> filter -> ...) ara tahsisatlardan kaçınmak istiyorsak.

Örnek:

let numbers = Array(1...1_000_000) let lazyNumbers = numbers.lazy.map { $0 * 2 }.filter { $0 % 3 == 0 } let first = lazyNumbers.first // İlk uygun eleman için işlem zinciri ancak şimdi hesaplanacak!

Tuzaklar:

  • Hesaplamalar, her .lazy sequence geçişinde tekrar tekrar sıfırdan yapılır.
  • Çağrı sırasına bağlıdır: Eğer verilere farklı koşullarla birkaç kez geçmek gerekiyorsa — veriler yeniden hesaplanacaktır.
  • Ertelenmiş işlemler, içsel closure'larda yan etkiler varsa beklenmedik yan etkilerin kaynağı olabilir.

Yanıtı zorlayıcı bir soru.

Bir dizide .map { ... } çağrısı ile .lazy.map { ... } çağrısı arasındaki fark nedir?

Cevap:

  • .map { ... }, closure'ı her elemana uygulayarak hemen yeni bir dizi döner ve yani tüm elemanlar işlenir ve bellek içinde saklanır.
  • .lazy.map { ... }, hemen bir dizi döndürmez, hemen elemanların işlenmesini yapmayan lazy-sequence (sarmalayıcı) döndürür, yalnızca onlara erişildiğinde işler.

Örnek:

let a = Array(1...10) let eagers = a.map { $0 * 2 } // 10 eleman içeren bir dizi let laziers = a.lazy.map { $0 * 2 } // Hemen sonuç içermeyen LazySequence

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri.


Hikaye

Büyük bir projede, geliştirici büyük bir veri dizisine birkaç map, filter, reduce çağrıları uyguladı, ancak .lazy kullanmadı. Bu, her ara adımda büyük dizilerin zamanla tahsis edilmesine yol açtı, bellek tüketimini neredeyse iki katına çıkardı ve bazı düşük RAM'li cihazlarda çökmelere neden oldu.


Hikaye

Kod bloğunda, içsel kapalı alanında (örneğin, map/filter içinde olay gönderme veya yazdırma) yan etkili bir lazy sequence kullanıldı. Geliştirici bu işlemin hemen gerçekleştirileceğini bekliyordu, ancak olay hiç gerçekleşmedi — çünkü lazy sequence elemanlarına bir kez bile erişilmedi ve olay kodu hiç çağrılmadı. Sonuçta, günlükler ve metrikler hatalıydı.


Hikaye

Büyük bir veritabanından veri toplama sırasında, lazy sequence birkaç geçişle birleştirildi (örneğin, iki kez first arandı, sonra count hesaplandı). Lazy sequence üzerinden her geçiş, işlemleri tamamen yeniden hesaplamayı başlattı — bu, iki kat yavaşlamaya ve sisteme gereksiz yüklemeye yol açtı. Normal bir diziye geçildiğinde sorun kayboldu.