고차 함수 사용

Yoon Yeoung-jin·2022년 3월 9일
0

iOS 개발

목록 보기
5/11

고차함수란?

  • 다른 함수를 전달인자로 받거나 함수 실행의 결과를 함수로 반환하는 함수를 뜻한다.

map 함수 사용

  • 컨테이너 내부의 기존 데이터를 변형하여 새로운 컨테이너를 생성한다.
  • 클로저 상수를 통해 코드의 재사용이 용이해지고 컴파일러 최적화 측면에서 성능이 좋아진다.
import UIKit
import Foundation

func normalExample() {
    
    let numbers: [Int] = [0, 1, 2, 3, 4]
    var doubledNumbers: [Int]
    var string: [String]
    
    doubledNumbers = [Int]()
    string = [String]()
    
    for num in numbers {
        doubledNumbers.append(num * 2)
        string.append("\(num)")
    }
    
    print(doubledNumbers)
    print(string)
}

func mapExample() {
    let numbers: [Int] = [0, 1, 2, 3, 4]
    var doubledNumbers: [Int]
    var string: [String]
    
    // numbers의 각 요소를 2배하여 새로운 배열 반환
    doubledNumbers = numbers.map({ (num: Int) -> Int in
        return num * 2
    })
    // numbers 의 각 요소를 문자열로 변환하여 새로운 배열 반환
    string = numbers.map({ (num: Int)->String in
        return "\(num)"
    })
    
    print(doubledNumbers)
    print(string)
}

func mapExample2() {
    let numbers: [Int] = [0, 1, 2, 3, 4]
    var doubledNumbers: [Int]
    var string: [String]
    
    doubledNumbers = numbers.map({ $0 * 2})
    string = numbers.map({ "\($0)"})
    
    print(doubledNumbers)
    print(string)
}

print("==================================")
print("[*] 고차 함수를 사용 안한 로직")
var start = CFAbsoluteTimeGetCurrent()
normalExample()
var processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")

print("[*] 고차 함수를 사용한 로직 (Map)")
start = CFAbsoluteTimeGetCurrent()
mapExample()
processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")

print("[*] 고차 함수를 사용한 로직 2 (Map)")
start = CFAbsoluteTimeGetCurrent()
mapExample2()
processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")
==================================
[*] 고차 함수를 사용 안한 로직
[0, 2, 4, 6, 8]
["0", "1", "2", "3", "4"]
경과 시간: 0.0030128955841064453
[*] 고차 함수를 사용한 로직 (Map)
[0, 2, 4, 6, 8]
["0", "1", "2", "3", "4"]
경과 시간: 0.00010097026824951172
[*] 고차 함수를 사용한 로직 2 (Map)
[0, 2, 4, 6, 8]
["0", "1", "2", "3", "4"]
경과 시간: 8.499622344970703e-05

filter 사용

  • 컨테이너 내부의 값을 걸러서 새로운 컨테이너로 추출한다.
  • filter의 매개변수로 전달되는 함수의 반환 타입은 Bool 이다.
  • true면 값을 포함하고, false면 값을 배재한다.
import UIKit
import Foundation

func orignalMethod() {
    let numbers: [Int] = [0, 1, 2, 3, 4]
    var filtered: [Int] = [Int]()
    for num in numbers {
        if num % 2 == 0 {
            filtered.append(num)
        }
    }
    print(filtered)
}

func filterMethod() {
    let numbers: [Int] = [0, 1, 2, 3, 4]
    let evenNumbers: [Int] = numbers.filter{ (num: Int) -> Bool in
        return num % 2 == 0
    }
    print(evenNumbers)
}

func filterMethod2() {
    let numbers: [Int] = [0, 1, 2, 3, 4]
    let evenNumbers: [Int] = numbers.filter { $0 % 2 == 0 }
    print(evenNumbers)
}

print("==================================")
print("[*] 고차 함수를 사용 안한 로직")
var start = CFAbsoluteTimeGetCurrent()
orignalMethod()
var processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")

print("[*] 고차 함수를 사용한 로직 (filter) ")
start = CFAbsoluteTimeGetCurrent()
filterMethod()
processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")

print("[*] 고차 함수를 사용한 로직 (filter) 2 ")
start = CFAbsoluteTimeGetCurrent()
filterMethod2()
processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")
==================================
[*] 고차 함수를 사용 안한 로직
[0, 2, 4]
경과 시간: 0.007430911064147949
[*] 고차 함수를 사용한 로직 (filter) 
[0, 2, 4]
경과 시간: 0.0005249977111816406
[*] 고차 함수를 사용한 로직 (filter) 2 
[0, 2, 4]
경과 시간: 0.0001399517059326172

reduce 사용

  • 컨테이너 내부의 콘텐츠를 하나로 통합해준다.
  • 정수 배열이면 전달 받은 함수의 연산 결과로 합쳐주고, 문자열 배열이면 문자열을 하나로 합쳐준다.
  • 첫 번째 매개변수를 통해 초기값을 정할 수 있다. ( 해당 초기값을 클로저를 통해 $0으로 사용 가능하다.)
import UIKit
import Foundation

func originalMethod() {
    let someNumbers: [Int] = [2, 4, 6]
    var result: Int = 0
    
    for num in someNumbers {
        result += num
    }
    print(result)
}

func reduceMethod() {
    let someNumbers: [Int] = [2,4,6]
    let sum: Int = someNumbers.reduce(0, {
        (first: Int, second: Int) -> Int in
        return first + second
    })
    print(sum)
}

func reduceMethod2() {
    let someNumbers: [Int] = [2, 4, 6]
    let sum: Int = someNumbers.reduce(0, { $0 + $1 })
    print(sum)
}

print("==================================")
print("[*] 고차 함수를 사용 안한 로직")
var start = CFAbsoluteTimeGetCurrent()
originalMethod()
var processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")

print("[*] 고차 함수를 사용한 로직 (reduce) ")
start = CFAbsoluteTimeGetCurrent()
reduceMethod()
processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")

print("[*] 고차 함수를 사용한 로직 (filter) 2 ")
start = CFAbsoluteTimeGetCurrent()
reduceMethod2()
processTime = CFAbsoluteTimeGetCurrent() - start
print("경과 시간: \(processTime)")
==================================
[*] 고차 함수를 사용 안한 로직
12
경과 시간: 9.09566879272461e-05
[*] 고차 함수를 사용한 로직 (reduce) 
12
경과 시간: 9.393692016601562e-05
[*] 고차 함수를 사용한 로직 (filter) 2 
12
경과 시간: 8.702278137207031e-05

결론

  • 생각보다 성능 차이가 많이 난다.
  • 고차 함수를 많이 사용하는게 매우매우매애애애애우 좋다.
profile
신기한건 다 해보는 사람

0개의 댓글