Swift는 정말 파이썬보다 빠를까?

애플은 Swift가 파이썬보다 몇 십배 빠르다고 주장하고 있는데, 실질적으로는 파이썬이 더 빠른 것 같이 느껴지는 (심지어 pypy도 아니고) 경우가 너무나 많다. 물론 “어떤 언어가 더 빠르냐”는 질문만큼 바보같은 것도 없긴한데, 개인적으로는 애플이 말하는 것과 반대인 것 같은 체감이 많아서 한 번 확인해보았다. Swift는 정말 파이썬보다 빠를까? 더보기

[Swift] 연관 타입(Associated Type)

연관타입(Associated Type)

Objective-C의 Associated Object와 비슷한 명칭이라 좀 헷갈릴 수 있는데, 연관타입은 프로토콜 등에서 현재 타입과 관련이 있는 타입을 의미한다.

연관타입은 프로토콜의 일부에 쓰이는 어떤 타입에 대한 플레이스홀더같은 것으로 프로토콜이 실제로 적용되기 전에는 사용되지 않는 타입1을 말한다. 연관타입은 typealias 키워드를 통해 정의한다. 다음 예는 Container라는 프로토콜의 정의이다.

protocol Container {
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i:Int) -> ItemType { get }
}

위 프로토콜은 세 가지 특정을 정의하고 있다. [Swift] 연관 타입(Associated Type) 더보기

String in Swift

Swift의 문자열

수정 (2015. 12. 07) : Swift2.0에서부터 문자열은 더 이상 Collection 타입이 아니므로 [Character] 타입으로 변경할 수 없으며, advance() 함수 역시 전역 함수에서 제거되고 Index 타입의 메소드로 변경되었다. NSString은 유니코드 문자열을 UTF16으로 인코딩한 바이트배열로 문자를 다루는데 비해, Swift의 문자열은 유니코드 문자열의 복잡 다단한 특성들을 정확히 반영하기 위해 애써서 디자인한 흔적들이 눈에 띈다. 보다 자세한 내용에 대해서는 따로 포스팅하겠다.

Swift의 문자열은 유니코드 문자열이고, 유니코드의어떤 특징들(여러개의 스칼라 코드가 하나의 문자로 결합하는 등)로 인해서 내부적으로는 단순 배열이 아니다. 따라서 Swift의 문자열은 인덱스에 의한 랜덤액세스를 지원하지 않는다. 즉, NSStringcharacterAtIndex:와 동일한 메소드를 지원하지 않는다. 컨셉상, Swift의 문자열은 배열보다는 양방향 리스트에 더 까운 구조이다.

문자열 내 개별문자(Character)와 범위의 인덱스들은 String.Index라는 불투명 타입에 의해 구현되며, 이 타입은 BidirectionalIndex라는 프로토콜 타입이다. 따라서 특정 위치의 문자를 얻기 위해서는 먼저 해당 문자열에 startIndex 값을 물어본 다음, 표준 함수인 —advance()를 사용하여 해당 위치 인덱스로 순차적으로 이동하고– 이 시작 인덱스의 advancedBy() 메소드를 이용해서 해당 위치로부터 원하는 만큼의 오프셋을 준 인덱스를 구한 후, 이 인덱스를 이용한 subscription으로 특정 위치의 문자를 구할 수 있다. (참 어렵게도 해놨다)

let digits = "0123456789"
let position = 3
let index = digits.startIndex.advancedBy(position)
let character = digits[index]

이를 이용하면 문자열의 뒤에서부터 접근하는 경우에

let index2 = digits.endIndex.advancedBy( -1 * position)
let character2 = digits[index2]

이런 식으로 advance() 함수의 두 번째 인자에 음수값을 주어 뒤에서부터 세어 나갈 수 있다.

메모리를 좀 더 많이 쓰는 대신 타이핑의 수고로움을 더는 방법으로는 문자열을 배열로 캐스팅하면 Character의 배열을 얻게 된다는 점을 착안하여,

let character3 = Array(digits)[4]

라고 쓰는 방법도 있긴하다.

Swift 2.0에서 문자열은 더 이상 집합 타입이 아니며, 따라서 [Characters] 타입으로 변환되지 않는다. 이는 문자열의 개수를 세는 countElement() 등의 함수의 비효율성을 극복하기 위해서, 단일 문자열이 여러 가지 타입으로 인코딩된 데이터 맵을 가지는 형태로 변환되었다.

좀 더 세련된 방법으로 문자열을 정수 인덱스를 지원하도록 서브스크립트를 확장하는 방법이 있다.

extension String {
    subscript(integerIndex: Int) -> Character {
        if integerIndex >= 0 {
            let index = startIndex.advancedBy(integerRange.startIndex)
            return self[index]
        }

    }

    subscript(integerRange: Range<Int>) -> String {
        let start = startIndex.advancedBy(integerRange.startIndex)
        let end = startIndexBy(integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

위 서브스크립트에서 정수 인덱스가 음수인 경우, 파이썬과 비슷하게 뒤쪽에서부터 문자를 출력하도록 하는 것도 가능할 것이다.

[Swift] 코어 이미지

Beginning Core Image in Swift

http://www.raywenderlich.com/76285/beginning-core-image-swift

코어 이미지는 이미지에 손쉽게 필터처리를 할 수 있는 강력한 프레임워크이다. 이는 어지간한 기본적인 사진 효과를 만들어낼 수 있는데, CPU 혹은 GPU 기반으로 프로세싱하고 있어서 매우 빠르다. 그냥 빠른 게 아니라 매우 빠르기 때문에 리얼타임으로 비디오 프레임에 적용될 수도 있다.

코어 이미지 필터는 여러 필터가 연쇄적으로 하나의 사진이나 비디오 프레임에 한꺼번에 적용될 수 있다. 이 때 여러 필터는 하나의 필터로 결합되어 이미지에 적용된다. 이런 방식은 한 번에 하나씩 이미지에 적용되는 것에 비해 훨씬 효율적이다. [Swift] 코어 이미지 더보기