Lazy Collection / Sequence
Lazy Sequence
'ler tüm öğelerinde değil, ihtiyaç halinde çağırıldığı dizilerdir. Özellikle büyük diziler ile çalışırken bazı durumlar için performansı olumlu etkisi olacaktır.
Örneğin:
let numbers = Array(1...100000)
let doubled = numbers.map { $0 * 2 }
Yukarıdaki map fonksiyonu tüm değerleri için 2 ile çarpma işlemini yapacaktır. Ancak tamamına değil sadece belli bir koşula uyan değerlere yapmak isteyebiliriz. Bu durumda lazy kullanmamız bizim için iyi olacaktır.
Örnegin; sayılardan oluşan bir dizimiz olsun ve 2 ye bölünebilenleri 2 ile çarpımını hesaplamak isteyelim. Lazy
kullanmadığımız durumda önce filter
fonksiyonuna çalışacaktır ve daha sonra ise map
fonksiyonuna çalışacaktır. Print yardımıyla fonksiyonun nasil çalıştığını görebiliyoruz.
var numbers: [Int] = [1, 2, 3, 6, 9]
let modifiedNumbers = numbers
.filter { number in
print("Even number filter")
return number % 2 == 0
}.map { number -> Int in
print("Doubling the number")
return number * 2
}
print(modifiedNumbers)
/*
Even number filter
Even number filter
Even number filter
Even number filter
Even number filter
Doubling the number
Doubling the number
[4, 12]
*/
Bu şekilde kullanırsak beklediğimiz değer en son hesaplanacaktır. Bu durum da yapılan işi artıracak ve daha fazla bellek kullanımına ihtiyaç duyacaktır. Peki aynı örneği Lazy
kullanarak yapsaydık nasıl bir sonuç elde edecektik ?
let modifiedLazyNumbers = numbers.lazy
.filter { number in
print("Lazy Even number filter")
return number % 2 == 0
}.map { number -> Int in
print("Lazy Doubling the number")
return number * 2
}
print(modifiedLazyNumbers)
// Prints:
// LazyMapSequence>, Int>(_base: Swift.LazyFilterSequence>(_base: [1, 2, 3, 6, 9], _predicate: (Function)), _transform: (Function))
İlk goze carpan nokta print kismi oluyor. Lazy
oldugundan ve henuz dizideki bir degeri cagirmadigimiz icin bu sekilde gosterilmektedir. Ancak degeri istedigimizde, sadece istenilen duruma kadar ki kısım print
edilecektir.
print(modifiedLazyNumbers.first!)
/*
Prints:
Lazy Even number filter
Lazy Even number filter
Lazy Doubling the number
4
*/
Lazy Sequence
'leri kullanirken dikkat edilmesi gereken durum talep edilene kadar fonksiyonun cağırılmasını erteler. Bu durumda sonuç değerlerini bir çıktı dizisinde saklamadığı anlamına gelmektedir ve her istek yapıldığında çağrılma işlemi tekrar tekrar yapılmaktadır. Eğer değerleri hazırda bulundurmak gerekiyorsa Lazy
kullanılmamalıdır.
Sayı olarak fazla bir dizimiz varsa tum degerlerine bir islem yapmak değil de sadece koşula uyan ilk değeri hesaplamak istersek lazy kullanmak mantıklı bir durum olacaktır.
let collectionOfNumbers = (1…1000000)
let lazyFirst = collectionOfNumbers.lazy
.filter {
print("filter")
return $0 % 2 == 0
}.first
print(lazyFirst) // Prints: 2
Ancak yukaridaki verilen kod orneginin daha basit bir kod ile yapilabilmektedir.
let firstWhere = collectionOfNumbers.first(where: { $0 % 2 == 0 })
print(firstWhere) // Prints: 2