Sloth in Swift

Why is lazy used here?

 extension SequenceType { func mapSome<U>(transform: Generator.Element -> U?) -> [U] { var result: [U] = [] for case let x? in lazy(self).map(transform) { result.append(x) } return result } } 

this extension takes a conversion function that returns optional, and returns an array of only those values ​​that were converted to nil

Why not just use self.map(transform) ? need laziness here?

+7
lazy-evaluation swift swift2
source share
2 answers

It avoids creating an intermediate array.

 self.map(transform) 

returns an array containing the conversion results of all the elements of the sequence that will then go through to build the resulting array with elements other than nil.

 lazy(self).map(transform) 

- a sequence of transformed elements, which then iterates to get non-zero elements. Transformed elements are calculated during enumeration. (Each call to next() on a lazy sequence produces one element, transforming the next element in the original sequence.)

Both methods work. The tape method will probably work better for large sequences, but it can depend on many factors (size from the array, whether the elements are values ​​or reference types, how expensive the elements of the array are, etc.). For small arrays, the lazy method is likely to be slower due to the extra overhead. In a particular application, profiling with tools helps you decide which method to use.

+11
source share

As Martin R mentioned, lazy() avoids creating an intermediate array. However, if I compare the execution time of a function with arrays of different sizes, you will find that lazy() "only" 10% faster.

Interestingly, you will find that lazy() designed for arrays with less than 200 elements 2 times faster and gets more elements almost equally fast than a function without conversion (10% faster).

(Tested with Xcode 6.4 and Xcode 7 with global functions and a protocol extension in the Playground as (compiled) source files)

So lazy() more likely to be used for Sequences , where you don't know if it is finite. Then for loops, they are probably used with break or return :

 for element in lazy(sequence).map{ ... } { if element == 1000 { break } // use element } 

If you call a map on an infinite Sequence (e.g. 1,2,3 ...), the execution will also be infinite. With lazy() conversion and execution are β€œdelayed," so you can more efficiently handle "large" and infinite sequences if you exit the loop to the last element.

+5
source share

All Articles