Swift 4: «filter.count» против «for loop with where», почему «filter.count» быстрее? - PullRequest
0 голосов
/ 26 октября 2018

Я тестирую на коллекции Swift вот код:

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 })
}

Этот код печатает

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

Как видите, первая функция подсчета работает быстрее, чем вторая. Кто-нибудь знает почему?

Edit:

Спасибо всем, я изменил код в соответствии с предложением, это новые результаты с использованием XCode с агрессивной оптимизацией:

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.

результаты с использованием Xcode с самой быстрой / самой маленькой оптимизацией

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.

Это результат использования Swift-компилятора 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.

Итак, похоже, что фильтр, безусловно, менее эффективен, чем цикл for и функция Reduce. Также кажется, что функция Reduce может быть быстрее, чем цикл for, есть идеи для этого доказательства?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...