Limit the results of a Swift array filter to X for performance

前端 未结 2 1781
天命终不由人
天命终不由人 2021-01-03 02:15

I have about 2000 elements in my array, and when it is filtered, I would like to end the filtering as soon as I have 5 elements in my filtered array.

Currently it i

2条回答
  •  误落风尘
    2021-01-03 02:59

    You can use .lazy too boost the performance a bit:

    let numbers: [Int] = Array(0 ..< 2000)
    
    let result: AnySequence = numbers
        .lazy
        .filter {
            print("Calling filter for: \($0)")
            return ($0 % 3) == 0
        }
        .prefix(5)
    
    print(Array(result))
    

    This will call the filter function only for the first 15 values (until it finds 5 that pass the filter).

    Now you can concentrate on boosting the performance of the filter itself. E.g. by caching values. You don't have to do this but if some values keep repeating, it can boost the performance a lot.

    let numbers: [Int] = Array(0 ..< 2000)
    var filterCache: [Int: Bool] = [:]
    
    let result: AnySequence = numbers
        .lazy
        .filter {
            if let cachedResult = filterCache[$0] {
                return cachedResult
            }
    
            print("Calling filter for: \($0)")
            let result = (($0 % 3) == 0)
    
            filterCache[$0] = result
    
            return result
        }
        .prefix(5)
    
    print(Array(result))
    

    You can apply this method directly to your function.

    Also note that to boost performance, you should either:

    • save ((row.value as? String)?.lowercased())! into a local variable because it is executed multiple times

    • simplify the expression using options:

     let result: AnySequence = providerArray
         .lazy
         .filter {
           $0.range(of: row.value as! String, options: [.caseInsensitive]) != nil
         }
         .prefix(5)
    

提交回复
热议问题