이번에 코딩테스트를 Swift로 해보려고 해서 찾아본 코드 !
문자열을 다룰 떄 유용하게 사용하지 싶다.
extension String {
subscript(_ index: Int) -> Character {
return self[self.index(self.startIndex, offsetBy: index)]
}
}
// 얘는 범위 설정 가능
extension String {
subscript(_ range: Range<Int>) -> String {
let fromIndex = self.index(self.startIndex, offsetBy: range.startIndex)
let toIndex = self.index(self.startIndex,offsetBy: range.endIndex)
return String(self[fromIndex..<toIndex])
}
}
좀 더 찾아보니, Swift의 문자열에서는 word[index]
이렇게 접근하는 것만으로도 O(n)
의 시간 복잡도를 가진다고 한다. 결국 위의 Extension
도 시간 복잡도적인 문제는 여전히 존재한다고 보면 된다.
그래서 생각한 방법은 Array
로 만들어서 해당 문자에 접근을 하고 다시 String
으로 만들던가 하는 경우가 시간 복잡도 면에서는 유리하다고 생각한다.
물론 문자열 내부 문자에 접근하는 경우가 많다면 시도 하는게 좋고, 그렇지 않다면 추천하지는 않는다. 이렇게 생각하게된 계기로는, 만약 문자 전체에 접근하는 코드를 작성한다면 단순히 생각 했을때 O(n^2)
의 복잡도를 가지므로 배열로 형변환 후 접근을 한다음 문자열로 접근하는 것은 O(2n+m)
이라고 생각하기 때문이다.
O(n^2)
인 이유는 하나의 문자에 접근하는 시간O(n)
전체 문자수 n 따라서O(n * n)
이 나옵니다.
O(n)
O(n)
따라서 O(2n + M)
제 생각이 틀릴수도 있기 때문에 너무 맹신하시면 안되지만, 저의 짧은 생각으로는 형변환의 방식이 O(n^2)
는 절대 걸리지 않는다라고 생각했습니당.
스위프트 성능에 대해서 알아 보던 중, 힙에 저장되는 참조 유형(클래스, 문자열 등)의 다중 생성을 피하는 방법에 대해서 나와 있는 글을 보고 정리하려고 합니다.
문자열은 스택에 저장되는 경우도 있고 힙 영역에 사용되는 경우도 있습니다 ! - 김정님 Medium
예를 들어 함수 내부의 변수에 문자열을 할당하고 이를 여러 번 호출해야하는 경우에 힙에 자주 저장되는 문제가 있다 이는 성능을 저하시키는 요인이 된다.
enum Color { case blue, green, gray }
enum Orientation { case left, right }
enum Tail {case none, tail, bubble }
var cache = [String : UIImage]()
func something(color: Color,orientation: Orientation, tail: Tail) -> UIImage{
let key = "\(color):\(orientation):\(tail)"
if let image = cache[key] {
return image
}
}
위 코드는 키가 문자열인 이미지 맵이 있고, 다운로드하거나, 캐시에서 가져와야 한다는 경우에 문자열 키를 생성하는 함수를 계속 호출해야 합니다. 이는 힙에 저장하는 빈도가 늘어나므로 좋지 않습니다.
이 부분을 해결하는 방법으로는 현재 key
의 문자열을 구조체로 만들면 해결이 됩니다. 구조체를 만드는 것은 스택에 할당되며, 시간이 많이 걸리는 프로세스가 아니기 때문에 성능향상에 많은 도움이 됩니다
// cache의 key 타입을 구조체로 받음
var cache = [Attributes : UIImage]()
struct Attributes: Hashable {
var color: Color
var orientation: Orientation
var tail: Tail
}
func something(color: Color, orientation: Orientation, tail: Tail) -> UIImage {
let key = Attribute(color: color, orientation: orientaion, tail: tail)
...
}
참조
https://medium.com/macoclock/swift-struct-vs-class-performance-29b7be73d9fd