seegongsik
알고리즘

어떻게 빠르기를 재는 자

어떤 방법이 더 빠른지 알고 싶으면 초시계로 재면 될 것 같다. 그런데 컴퓨터가 빠르면 느린 방법도 빨라 보인다. 진짜 차이는 칸이 적을 때는 숨어 있다가 칸이 확 늘어날 때 드러나요. 그래서 빠르기는 초가 아니라 '칸이 늘면 일이 얼마나 늘어나는가'로 잰다.

01

초 대신 횟수

초로 재면 헷갈린다. 빠른 컴퓨터에서는 느린 방법도 빨라 보이기 때문이다.
그래서 초 대신 '몇 번 일하는가'를 센다.
칸이 n개일 때 일하는 횟수는 방법마다 달라요.

입력 크기 고르기
하나씩n번
?
반씩log n번
?
칸이 커질수록 둘의 횟수 차이가 벌어져요.

입력 크기를 고르면 방법마다 일하는 횟수가 나온다. (하나씩 = n번 · 반씩 = 훨씬 적은 횟수)

칸이 적을 때는 둘이 비슷해 보인다.
8칸이면 하나씩은 8번, 반씩은 3번이라 차이가 별로 없다.
그럼 칸을 확 늘리면 어떻게 될까요?

02

키우면 생기는 일

여기서 진짜 차이가 보인다.
n을 키워 보면 어떤 방법은 칸이 느는 만큼만 천천히 늘고, 어떤 방법은 칸이 두 배가 될 때마다 일이 네 배로 뛴다.
n 곱하기 n, 이것을 n²이라고 써요.

2n4n 곱하기 n
지금 n = 2 · n 곱하기 n = 4
칸이 두 배가 될 때마다 n은 두 배, n 곱하기 n은 네 배로 뛰어요.

버튼을 누를 때마다 칸이 두 배가 된다. n은 칸만큼 늘지만 n²은 칸이 커질수록 폭발하듯 늘어요.

n²이 무서운 건 칸이 많을 때다.
100칸이면 n은 100이고 n²은 10000이다. 1000칸이면 n은 1000, n²은 백만이 된다.
작게 시작해도 금세 손쓸 수 없을 만큼 커져요.

03

세 곡선을 나란히

세 가지 자라는 모양을 나란히 두면 한눈에 보인다.
log n은 칸이 아무리 커져도 거의 올라가지 않는다.
n은 비스듬히 곧게 오르고, n²은 위로 휘어 저 멀리 치솟아요.

n
같은 n에서도 n 곱하기 n은 저 위로, log n은 거의 바닥에 붙어 자라요.

곡선을 하나씩 켜서 견준다. 같은 n에서도 log n · n · n²의 높이가 완전히 달라요.

이제 반씩 자르기가 왜 그렇게 빨랐는지 알 수 있다.
반씩 자르기는 log n, 칸이 천 개여도 열 번쯤이면 끝난다. 하나씩 보기는 n, 천 개면 천 번이 걸린다.
승부를 가른 것은 자라는 모양이에요.

04

큰 항만 남긴다

실제 횟수를 세어 보면 3n²+5n+9처럼 식이 지저분하다.
그런데 n이 아주 커지면 n²이 나머지를 모두 압도한다.
그래서 작은 항은 지우고 가장 빨리 자라는 n²만 남겨요.

3n2+ 5n+ 9
아직 지울 게 남았어요
n이 아주 커지면 작은 항과 앞 숫자는 묻혀요. 큰 항만 남긴 게 빅오예요.

누를 때마다 작은 항과 앞의 숫자가 하나씩 지워진다. 3n²+5n+9에서 n이 크면 n²만 남고, 그 모양을 적은 것이 빅오(O)예요.

앞의 숫자도 지운다. 3n²이든 100n²이든 자라는 모양은 똑같이 n²이기 때문이다.
그래서 그냥 O(n²)이라고 적는다.
빅오는 '칸이 많을 때 어떤 모양으로 자라는가'를 한 줄로 적은 이름표예요.

05

여기까지 온 길

정리하면 이렇다. 빠르기는 초가 아니라 자라는 모양으로 잰다.
칸 n이 커질 때 log n은 거의 늘지 않고, n은 칸만큼 늘고, n²은 폭발한다.
식이 복잡해도 가장 큰 항 하나만 보면 되고, 그것을 적는 표시가 빅오예요.

항을 누르면 자라는 모양이 켜져요

세 항을 하나씩 켜며 한 줄로 정리한다. log n은 거의 평평, n은 비스듬히, n²은 위로 폭발. 큰 항만 보면 돼요.

이제 어떤 방법을 보면 초를 재지 않고도 빠른지 가늠할 수 있다.
칸이 두 배가 될 때 일도 두 배면 괜찮고, 네 배로 뛰면 조심해야 한다.
좋은 방법은 큰일 앞에서도 천천히 자라는 방법이에요.

한 줄 정리빠르기는 초가 아니라 자라는 모양으로 잰다. 입력 칸 n이 커질 때 일이 얼마나 늘어나는지를 보는 것이다. log n은 거의 늘지 않고 n은 칸만큼 늘며 n²은 폭발한다. 식이 복잡해도 가장 크게 자라는 항 하나만 남기면 되니, 3n²+5n+9는 그냥 n²이다. 이렇게 큰 항만 보는 표시가 빅오(O)다. 그래서 큰 데이터에서는 반씩 자르기가 하나씩보다 비교가 안 될 만큼 빨라요.
← 알고리즘
이 페이지가 도움 됐다면 후원하기