Swift 4: "filter.count" vs "for loop with where", why 'filter.count' is faster?

Viewed 394

I'm testing on Swift collection here is the code:

func printTimeElapsedWhenRunningCode(title:String, operation:()->())
{
  let startTime = CFAbsoluteTimeGetCurrent()
  operation()
  let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
  print("Time elapsed for \(title): \(timeElapsed) s.")
}

extension Sequence
{
  func count(where predicate: (Element) -> Bool) -> Int
  {
    return filter(predicate).count
  }

  func count2(where predicate: (Element) -> Bool) -> Int
  {
    var c: Int = 0
    for element in self where predicate(element)
    {
      c += 1
    }
    return c
  }

  func count3(where predicate: (Element) -> Bool) -> Int
  {
    return reduce(into: 0) { if predicate($1) { $0 += 1 } }
  }
}

let ccc = 1...1000000

printTimeElapsedWhenRunningCode(title: "count Test") {
  let _ = ccc.count(where: { $0 % 2 == 0 })
}

printTimeElapsedWhenRunningCode(title: "count Test 2") {
  let _ = ccc.count2(where: { $0 % 2 == 0 })
}

printTimeElapsedWhenRunningCode(title: "count Test 3") {
  let _ = ccc.count3(where: { $0 % 2 == 0 })
}

This code prints

 Time elapsed for count Test: 18.0662090778351 s. 
 Time elapsed for count Test 2 : 28.3750340938568 s.

As you can see the first count function is faster than the second. Anyone knows why?

Edit:

Thank you all, I've modified the code as suggested, these are the new results using Xcode with aggressive optimization:

Time elapsed for count Test: 51.4916070699692 s.
Time elapsed for count Test 2: 51.3513959646225 s.
Time elapsed for count Test 3: 50.2809948921204 s.

results using Xcode with Fastest/Smallest optimisation

Time elapsed for count Test: 51.5341190099716 s.
Time elapsed for count Test 2: 51.3876320123672 s.
Time elapsed for count Test 3: 50.2216899394989 s.

These are the result using the Swift compiler swiftc -o

Time elapsed for count Test: 52.560210943222 s
Time elapsed for count Test 2: 51.3171380758286 s.
Time elapsed for count Test 3: 51.3849959373474 s.

So, it appears that filter is surely less efficient than the for loop and the reduce function. It also appears that the reduce function may be faster than the for loop, any idea for this evidence?

0 Answers
Related