Javascript/자료구조&알고리즘
[자료구조&알고리즘]배열과 오브젝트 성능 평가 (Big O)
이지영
2022. 6. 30. 11:32
Javascript에서 objects의 keys-values쌍은 index가 따로 없기 때문에 삽입, 제거, 탐색, 접근 등의 작업에 드는 시간이 arrays와 다르다.
예를 들어 arrays의 경우, 끝부분이 아닌 곳에 element가 삽입 혹은 제거되면
그 뒤의 모든 elments의 index가 한 칸 씩 뒤로밀려 재배열되기 때문에 선형 시간(O(n))이 걸리는 데에 반해,
objects의 keys-values쌍은 index가 따로 없기 때문에, 즉 순서 자체가 없기 때문에
arrays와 달리 같은 작업을 처리하는 데에 상수 시간(O(1))이 걸린다.
다만 value를 찾아야 하는 작업은 모든 keys를 확인해야하기 때문에 선형 시간이 걸린다.
object methods를 사용할 때에 각 method의 시간 복잡도를 파악해두면 좀 더 효율적인 알고리즘을 작성할 수 있다.
객체(Objects)
- 객체는 순서가 없지만 key와 value을 사용해 빠르다는 장점이 있다.
- Big O로 보는 성능은 다음과 같다.
- 삽입(Insertion) ⇒ O(1)
- 삭제(Removal) ⇒ O(1)
- 검색(Searching) ⇒ O(N)
- 접근(Access) ⇒ O(1)
객체 순회하기
- 객체의 요소는 인덱스(순서)가 없다. 객체의 값은 키를 통해서만 접근이 가능하다.
- 하지만 순회 가능하다!
Object.keys()
- 객체의 키 목록을 배열로 리턴한다.
- 객체 내장 메서드가 아니고, 객체 생성자인 Object 가 직접 가지고 있는 메서드이다.
const obj = {
name: 'melon',
weight: 4350,
price: 16500,
isFresh: true
}
Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']
- Object.keys() 가 리턴하는 값이 배열이기 때문에 이제는 반복문을 사용할 수 있다.
const keys = Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']
for (let i = 0; i < keys.length; i++) {
const key = keys[i] // 각각의 키
const value = obj[key] // 각각의 키에 해당하는 각각의 값
console.log(value)
}
Object.entries()
- ES6 에서 객체의 value 값을 배열로 반환하는 Object.values() 와 객체의 key, value 값을 배열로 반환하는 Object.entries() 가 추가되었다.
const values = Object.values(obj)
// values === ['melon', 4350, 16500, true]
const entries = Object.entries(obj)
/*
entries === [
['name', 'melon'],
['weight', 4350],
['price', 16500],
['isFresh', true]
]
*/
let obj = {
name: "kim",
age: 30,
height: 172,
};
console.log(Object.keys(obj)); //[ 'name', 'age', 'height' ]
console.log(Object.values(obj)); //[ 'kim', 30, 172 ]
console.log(Object.entries(obj)); //[ [ 'name', 'kim' ], [ 'age', 30 ], [ 'height', 172 ] ]
console.log(obj.hasOwnProperty("height")); //true
- 순서가 정해져 있어 객체보다 시간이 좀 더 오래 걸린다.
- 정렬될 필요가 있는 데이터, 정렬되어 있는 데이터를 보관하는데 유리하다
- 배열 시작에서 작업을 하는것이 끝에서 하는것보다 더 느리다
- 배열 연산의 Big O Notation
삽입 - 맨 앞일 때 : O(N), 맨 뒤일 때 O(1)
삭제 - 먠 앞일 때 : O(N), 맨 뒤일 때 O(1)
접근 - O(1)
탐색 - O(N)
배열 메소드의 Big O Notation
- push - O(1)
- pop - O(1)
- shift - O(N)
- unshift -O(N) =>push와 pop이 shift와 unshift 작업보다 빠름(비어 있는 배열일때 제외)
- concat - O(N + M) = O(N) : 여러 배열을 합쳐주는데 결합할 배열이 커질수록 끝에 붙일 배열의 크기만큼 시간도 그만큼 늘어날것
- slice - O(N) : 배열의 전체 혹은 일부를 복사함, 얼마나 복사할지에 따라 다름 = 배열의 길이에 따라 다름
- splice -O(N) : 인수가 2개일 때에는 삭제, 3개 이상일 때에는 추가
- sort - O(N * logN)
- 고차함수(forEach/map/filter/reduce/etc. - O(N)
=>배열의 기본적인 연산, 메소드들은 보통 O(N)이다.
접근, pop, push은 인덱스를 사용해서 접근하는 것과 똑같고 상수 시간걸림 빠름
총정리
객체는 거의 모든것을 더 빠르게 하지만 , 정렬되어 있지 않고
배열은 정렬 되어 있지만 ,끝에 추가하고 제거하는 작업이 느림 시작에 넣거나 빼면 처음부터 끝까지 영향을 받으면서 전부 인덱스를 다시 정리해야함