반응형
Notice
Recent Posts
Recent Comments
Link
NOW OR NEVER
시간 복잡도 본문
반응형
시간복잡도
빅오 표기법 Big-O notation
- 프로그램의 성능을 알기 위해 고려해야 하는 것들 : 입력으로 들어오는 데이터의 크기, 프로그램이 동작하는 하드웨어 성능, 프로그램을 실행 관리하는 운영체제 성능, 프로그램을 build하는 컴파일러 최적화, 프로그램이 thread 혹은 process 사용시 비동기 로직 고려
- 프로그램의 성능을 정확하게 파악하는 것은 불가능하므로 컴퓨터 과학자들은 대략적인 성능을 비교하기 위한 상대적인 표기법을 사용하기로 했다. 그것이 바로 빅오 표기법이다.
- 시간복잡도를 나타내기 위한 방법 중 하나
- 빅오 표기법의 상대적인 성능을 비교
- O(1) < O(log n) < O(n) < O(n log n) < O(n^2) < O(2^n) < O(n!)
- 상수시간<로그 시간<선형시간<선형로그시간<2차시간<지수시간<팩토리얼시간 라 불리기도 한다. 참고로 여기서의 log의 밑은 2이다.
- 빅오에 쓰인 n이 전부 같은 값이라고 가정할 때 O(1)이 가장 빠르고 위 순서대로 점점 느려진다.
- 지수시간이나 팩토리얼 시간 같은 경우 특정한 상황이 아니라면 가급적 사용하면 안된다.
- 코딩테스트에는 n^3이상 시간복잡도가 소요되는 경우는 거의 없다.
- 식에 계수나 상수 연산이 없는 이유 : 빅오표기법은 점근적 표기법을 따르기 때문이다.(점근적 표기법은 함수의 증감 추세를 비교하는 방법이다.)
선형시간
- 입력한 크기 만큼 loop를 도는 것
- 선형시간과 로그시간에는 어마어마한 차이가 존재: 예를 들어 n이 1024인 경우 선형시간은 1024번 루프를 돌지만 로그시간은 단 10번만 루프를 돌면 된다.
- O(n)
for(let i = 0; i < n; i += 1) { }
로그시간
- O(log n)
for(let i = 1; i <= n; i *= 2) { }
- 입력받은 n에 log를 씌운 만큼만 loop를 돌게 됨
선형 로그 시간
- O(n log n)
for(let i = 0; i < n; i += 1) { for(let j = 1; j <= n; j *= 2) { } }
선형지수 시간(2차 시간)
- 선형지수시간은 단순히 선형시간에 지수시간을 곱한 시간
- 2차 시간은 n의 제곱만큼만 루프를 돈다.
- O(n^2)
for(let i = 0; i < n; i += 1) { for(let j = 0; j < n; j += 1) { } }
빅오 표기법의 4가지 법칙
- 표기할 때 딱 두가지만 기억하면 된다.
- 상수항은 무시
// 계수 법칙에 의해 계수는 무시된다 // 그리하여 O(n+m)으로 표기된다. for(let i = 0; i < n * 6; i += 1) { } for(let i = 0; i < m * 3; i += 1) { }
- 상수항은 무시
- 가장 큰 항 외엔 전부 제거(무시)
// O(n^2 +n)이지만 작은항은 무시하여 O(n^2)으로만 표기해도 된다. for(let i = 0; i < n; i += 1) { } for(let i = 0; i < m * 3; i += 1) { for(let j = 0; j < n; j += 1) { } }
- 가장 큰 항 외엔 전부 제거(무시)
1. 계수 법칙
- 상수 k가 0보다 클 때 f(n) = O(g(n))이면 kf(n) = O(g(n))이다. n이 무한에 가까울 수록 상수 k의 크기는 의미가 없기 때문에 상수 k는 생략해서 표현한다. 하지만 상수 k가 클수록 실제 성능에는 영향을 미칠 수 있다.
- 예시
// 두 루프는 같은 O(n)으로 표기된다. for(let i = 0; i < n; i += 1) { } for(let i = 0; i < n * 5; i += 1) { }
2. 합의 법칙
- f(n) = O(h(n))이고 g(n) = O(p(n))이면 f(n) + g(n) = O(h(n)) + O(p(n))이다. 빅오끼리 더할 수 있다.
- 예시
// 두 루프를 합쳐 O(n + m)으로 표기할 수 있다. // 계수 법칙에 의해 5는 사라진다. for(let i = 0; i < n; i += 1) { } for(let i = 0; i < m * 5; i += 1) { }
3. 곱의 법칙
- f(n) = O(h(n))이고 (n) = O(p(n))이면 f(n) * g(n) = O(h(n)) * O(p(n)) 이다. 빅오끼리는 곱해질 수 있다.
- 2차 시간이나 선형로그 시간 같은 시간복잡도는 곱의 법칙을 통해 나온 것이다.
- 예시
// 두 루프를 합쳐 O(n^2)으로 표기할 수 있다. // 계수 법칙에 의해 5는 사라진다. for(let i = 0; i < n; i += 1) { for(let j = 0; j < n * 5; j += 1) { } }
4. 다항 법칙
- 다항식일 때 표현하는 방법
- f(n)이 k차 다항식이면 f(n)은 O(n^k)이다.
- 예시
// 다음 루프는 O(n^3)으로 표기할 수 있다. for(let i = 0; i < n * n * n; i += 1) { }
js에서 성능 측정 방법
Date 객체 이용
오래된 브라우저에서도 사용할 수 있으면서도 단순한 방법
시작시간을 구하고 로직을 돌린 다음 시간의 시작시간을 빼주면 로직의 작동시간을 알 수 있다. 이런 식으로 대략적으로 성능을 측정할 수 있다.
방법
const start = new Date().getTime(); // … const end = new Date().getTime(); console.log(end - start);
예시
console.log(“Start”); const start = new Date().getTime(); const N = 1000000000; let total = 0; for(let i = 0; i < =N; i += 1) { total += i; } const end = new Date().getTime(); console.log(end - start); console.log(“Finish”) // output //Start // 1114 //초로 환산하면 약 1.1초 정도 // Finish
'Algorithm' 카테고리의 다른 글
[프로그래머스] JAVA - 폰켓몬 (0) | 2024.05.20 |
---|---|
자료구조의 종류 (0) | 2022.02.16 |
자료구조와 알고리즘이란? (0) | 2022.02.15 |
Comments