이 글은 Swift Lee 의 글을 번역 한 글입니다!
출처: https://www.avanderlee.com/swift/performance-collections/
first(where:) != nil
대신에 contains
를 사용하자
여러 방법이 있지만 최상의 성능을 위해서 contains 를 사용하자
let numbers = [0, 1, 2, 3]
numbers.contains(1)
let numbers = [0, 1, 2, 3]
numbers.filter { number in number == 1 }.isEmpty == false
numbers.first(where: { number in number == 1 }) != nil
배열의 count
가 0인지 비교하는 대신 isEmpty
인지 확인하자
이유를 설명하는 가장 좋은 방법은 isEmpty 문서 를 인용하는 것 입니다.
[****Discussion]*** 컬렉션이 비어 있는지 확인해야 하는 경우, count 속성이 0인지 확인하는 대신 isEmpty 속성을 사용하십시오. RandomAccessCollection을 준수하는 컬렉션이 아니라면 count 속성에 액세스하면 컬렉션의 요소를 반복(iterate)합니다.*
isEmpty
는 항상 복잡도가O(1)
이고,count
는O(n)
이 될 수 있다. (RandomAccessCollection
프로토콜을 준수하지 않는 경우)
✅ Best practice
let numbers = []
numbers.isEmpty
❌ Bad practice
let numbers = []
numbers.count == 0
.isEmpty
로myString.isEmpty
myString == ""
myString.count == 0
.first
) 요소를 가져오자.first(where:)
은 첫 번째 요소를 찾는 즉시 순회를 중지하지만,.filter
로 모든 요소를 순회하고, .first
를 찾아오기에 훨씬 비효율적일 수 있음let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
let firstNegative = numbers.first(where: { $0 < 0 })
let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
let firstNegative = numbers.filter { $0 < 0 }.first
sorted()
는 복잡도가 O(*n* log *n*)
인 반면에,.min()
/ .max()
는 복잡도가 O(*n*)
이므로 더 효율적인 작업이다.let numbers = [0, 4, 2, 8]
let minNumber = numbers.min()
let maxNumber = numbers.max()
let numbers = [0, 4, 2, 8]
let minNumber = numbers.sorted().first
let maxNumber = numbers.sorted().last
.allSatisfy
를 사용하자
컬렉션의 모든 요소가 특정 조건에 부합하는지 확인하기 위해서,
.filter 로 특정 조건이 아닌 요소를 찾고 .isEmpty 를 통해서 조건이 아닌 요소가 없다. 를 확인하곤 하는데
Swift 4.2 에서 도입된 .allSatisfy
를 사용하는 것이 낫다.
🤔 왜 더 나을까? .allSatisfty 도 배열의 한 요소씩 순회하며 체크하고 O(n) 의 복잡도를 갖는데…
→ filter 는 확인 후, 배열을 리턴 하고 또 isEmpty 로 체크하지만 allSatisfy 는 확인만 하면 끝이니까?
- This approach is far more readable than the previous option, and anyone reading this code can immediately see the exact requirements that will cause this function to return
true
.- 훨씬 읽기 쉽고, Bool 을 리턴할 것이 더 명시적이어진다!
✅ Best practice
let numbers = [0, 2, 4, 6]
let allEven = numbers.allSatisfy { $0 % 2 == 0 }
❌ Bad practice
let numbers = [0, 2, 4, 6]
let allEven = numbers.filter { $0 % 2 != 0 }.isEmpty
SwiftLint
를 사용하자SwiftLint
에 구현되어 있다