iOS 개발/Swift

[TIL] Swift 에서 Array 를 탐색하는 방법들의 차이 (for in)

꽁치대디 2022. 7. 17. 22:05

[TIL] Swift 에서 Array 를 탐색하는 방법들의 차이 (for in)

프로그래머스에서 코딩테스트 문제를 풀다가 신기한 점을 발견했습니다.

 

Array 를 탐색하는데 인덱스로 탐색하는 것과 for in 을 이용하여 Array 의 원소에 직접 접근하는 것이 꽤나 많은 시간차이를 보인다는 것이었습니다.

 

https://school.programmers.co.kr/learn/courses/30/lessons/64062

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

제가 풀던 문제는 이 문제였는데, 효율성 테스트 부분을 통과하지 못하고 있었습니다.

 

그런데 다른 부분의 변경은 일절 없이, Array 를 탐색하는 부분의 방법만 살짝 변경해주었을 뿐인데 효율성 테스트를 통과하는 신기한 경험을 했습니다!

 

for in 루프를 이용해 Array 를 탐색한 경우 (코드 변경 전)

 

인덱스를 이용해 Array 를 탐색한 경우 (코드 변경 후)

 

저는 당연히 Array 의 count 가 O(n) 의 시간복잡도를 가지기 때문에 원소에 직접 접근하는 방식이 더욱 빠를 것이라고 생각했지만, 결과는 반대였습니다.

 

그래서 for 문을 이용할때 Array 의 원소에 직접 접근하는 for value in array 와 같은 방식과, 인덱스를 이용해 원소에 접근하는 for i in 0 ..< array.count 와 같은 방식이 어떤 차이점을 가지고 있는지 찾아봤습니다.

 

Swift 에는 아시다시피 Array 내장 메소드로 forEach 가 이미 존재하고 있고, 대부분의 글이 for in 방식과 forEach 를 비교하는 글 뿐이라 검색하는데 살짝 애를 먹었습니다.

 

조금 오래된 글이긴 하지만, StackOverflow 에서 관련된 글을 찾을 수 있었습니다. 아래는 제가 참고한 글의 링크입니다.

 

https://stackoverflow.com/questions/27876623/in-swift-which-loop-is-faster-for-or-for-in-why

 

In swift which loop is faster `for` or `for-in`? Why?

Which loop should I use when have to be extremely aware of the time it takes to iterate over a large array.

stackoverflow.com

 

우선 for in 방식이 어떻게 동작하는지 알 필요가 있었습니다.

 

 

위와 같이 for in 루프는 Array 의 generate() 메소드와 해당 메소드의 next() 메소드를 통해 인덱싱을 하고 있다는 것을 알 수 있었습니다.

 

해당 부분에서 처리해야할 부분이 생각보다 많기 때문에 당연히 Array 의 원소에 접근할 때는 인덱스를 이용하는게 더 빠르다는 것이 답변자의 주장입니다.

 

더 아래로 내려서 살펴보면 다른분들이 달아주신 답변을 확인할 수 있는데,

 

 

for in 루프는 다음 원소에 접근하기 위한 Call Object 인 Iterator 를 사용하기 때문에 인덱스를 이용해 접근하는 방법보다 느릴 수 밖에 없다고 합니다.

 


오늘은 for in 루프가 인덱스를 이용해 Array 의 원소에 접근하는것 보다 느리다는 것을 알게 되었지만, 해당 글의 모든 답변은 결국 코드의 결과는 똑같을 것이다 라는 의견을 포함하고 있었습니다.

 

어떤 답변은 우리는 작은 효율성 개선에 집착할 필요가 없다. 너무 과한 최적화는 모든 악의 근원이다 라는 다소 극단적인 내용을 포함하고 있기도 합니다.

 

물론 현재 제 단계에서 구현하게 될 프로그램들이 for 문과 같은 부분의 최적화에서 큰 차이를 보이지 않을 것이라는 사실은 잘 알고 있습니다.

 

하지만 저는 코딩테스트를 통과하는게 목적이었기도 하고, 해당 부분이 어떻게 동작하는지 알게 되었기 때문에 전혀 나쁜 경험은 아니었다고 생각합니다.

 

앞으로 코딩테스트 문제를 해결할때 왠만해서는~ 인덱스를 이용한 방법으로 처리하는 것이 좋을 것 같습니다.