JavaScript Loop Speed
Is 'for-in' really slow?
1. for-in vs. for-of ๐ฉโ๐ป
1. Why JavaScript have two for-loops?
Java ํ๋ก๊ทธ๋๋ฐ์ ํ ๋ ์ปดํ์ผ ๋ ์ฝ๋๋ฅผ ๋ดค๋๋ฐ for
๋ก ์์ฑํ ์ฝ๋๊ฐ while
๋ก ์ปดํ์ผ ๋๋ ๊ฒ์ ๋ณด๊ณ ๋งค์ฐ ์ ๊ธฐํ๋
์ ์ด ์๋ค. while
์ ์ฝ๋ ์์ฑ ์์ ์ ๋ฐ๋ณต ํ์๋ฅผ ๋ฏธ๋ฆฌ ์ ์ ์๊ณ Runtime ์ ์ ์ ์๋ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค๊ณ ๋ฐฐ์ ์๋ค.
ํ์ง๋ง ๋๋ถ๋ถ์ ์ธ์ด๋ ์์ฃผ ๊ณ ์ ์ ์ธ for-i
๋ฅผ ์ฌ์ฉํ๋ index ๊ธฐ๋ฐ์ ๋ฐ๋ณต๋ฌธ์ด ์๋ Iterable
๊ฐ์ฒด์ Elements ๋ฅผ
์ง์ ๋ฐ๋ณต์ํค๋ for
Syntax ๋ฅผ ์ ๊ณตํ๋ฉด์ do-while
๊ณผ ๊ฐ์ ๋ฐ๋ณต๋ฌธ์ด ์๋๋ฉด ์ฌ์ค์ ๋ฐ๋์ while
๋ก ์์ฑํ ํ์๊ฐ
์์ด์ ธ ์์ฑํ๋ ์ฌ๋์ ์ทจํฅ์ ๋ฐ๋ฅธ ์ ํ์ ๊ฐ๊น์์ก๋ค.
๊ทธ๋ ๋ค๋ฉด ํน์ while
์ ์ฌ์ฉํ๋ ๊ฒ์ด for
์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ ๋น ๋ฅธ๊ฐ์ ๋ํ ๊ถ๊ธ์ฆ์ด ์๊ฒจ ๊ฒ์์ ํด๋ณด์๊ณ , ์ป์ด๋ธ ๊ฒฐ๋ก ์
์ปดํ์ผ๋ฌ๊ฐ ์ต์ ํ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์ฐจ์ด๋ ๋ฏธ๋ฏธํ๊ณ ์ฑ๋ฅ์ ๋ชฉ์ ์ผ๋ก ์ ํํ์ง๋ ๋ง๋ผ๋ ๊ฒ์ด์๋ค.
JavaScript ๋ ๋ค๋ฅธ ์ธ์ด์ ๋ฌ๋ฆฌ forEach
๋ ์๋ for
๋ฐ๋ณต๋ฌธ์ด 2๊ฐ๋ ๋๋ค. for-await-of
์ ๊ฐ์ ๋น๋๊ธฐ
์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฐ๋ณต๋ฌธ์ ์ ์ธํ๊ณ ๋ for-of
์ for-in
์ด๋ค. ๋๋ถ๋ถ Monad ๋ฅผ ์ ์ฉํ๊ธฐ ์ํด ๋ฐฐ์ด์ Instance Methods ๋ก
๊ตฌํ๋ forEach
๋ฅผ ์ ์ธํ๋ฉด ํ๋์ for
๋ง ์กด์ฌํ๋ค. ์ฌ์ง์ด Swift ์ ๊ฒฝ์ฐ๋ Arrays, Sets ์ ๋ฌผ๋ก ์ด๊ณ , JavaScript
๋ก ์น๋ฉด Map
๋๋ Object
์ ์ ์ฌํ Key-Value
๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋ Dictionaries ๋ง์ ๋ for-in
๋ฐ๋ณต๋ฌธ ํ๋๋ก ๋ชจ๋ Iterable ๊ฐ์ฒด๋ฅผ ๋๋ฆด ์ ์๋ค.
๊ทธ๋ฐ๋ฐ ์ JavaScript ๋ for-of
์ for-in
2๊ฐ๋ ์กด์ฌํ๋ ๊ฒ์ผ๊น?
2. Is for-of faster than for-in?
์ฑ๋ฅ์ ์ฐจ์ด๊ฐ ์กด์ฌํ ๊น ๊ถ๊ธํด์ ์ฐพ์๋ณด๋ ๋๋ถ๋ถ์ ๋ธ๋ก๊ทธ์์ for-in
์ ๋ค๋ฅธ ๋ฐ๋ณต๋ฌธ์ ๋นํด ๋๋ฆฌ๋ค๊ณ ์ด์ผ๊ธฐํ๋ค. ๋ฌผ๋ก , Monad
๋ฅผ ์ ์ฉํ๊ธฐ ์ํ ๋ฐฐ์ด ๋ฉ์๋์ธ forEach
, map
, filter
์ ๊ฐ์ ๋ฐ๋ณต์ ๊ธฐ๋ณธ์ ์ธ for
, while
์ ๋นํ๋ฉด ์กฐ๊ธ ๋๋ฆฌ์ง๋ง
๊ฐ์ ธ๋ค ์ฃผ๋ ์ด์ ์ด ๋์ฑ ํฌ๊ธฐ ๋๋ฌธ์ ๋น๊ต ๋์์ด ์๋๋ค.
๋ฐฐ์ด ๋ฉ์๋๋ ์๋๋ฐ ์ ๋ ๋๋ฆฐ for-in
๋ฐ๋ณต๋ฌธ์ deprecated ๊ฐ ๋์ง ์๋๊ฑธ๊น?
for-of ์ for-in ์ ์ ์์ ์ฐจ์ด์ ์ ์ดํด๋ณด๋ฉฐ ์ด์ผ๊ธฐ ํ๊ฒ ์ง๋ง, ๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด ๋์ ์ ์ด์ ์ฉ๋๊ฐ ๋ค๋ฅด๋ค. ๋ฐฐ์ด์ for-in ๋ฅผ ์ฌ์ฉํด๋๊ณ ๋๋ฆฌ๋ค๊ณ ํ๋ ๊ฒ์ MDN - forโฆin ์ ์ค๋ช ์ ์ ๋๋ก ๋ณด์ง ์๊ณ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๊ฒ์ ์ข ๋ ์ ํํ ๋งํ๋ฉด ์๋ชป ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ฆฐ ๊ฒ์ด๋ค.
3. for-of
์ด๋ค ์ธ์ด์์๋ ๋ฐฐ์ด์ index
๊ธฐ๋ฐ์ด๊ณ , ๋ฐฐ์ด์ด๋ผ๋ ์ปจํ
์ด๋๊ฐ ๊ฐ๊ณ ์๋ ๊ฐ๊ฐ์ ์์ดํ
์ ๋ฝ์์ ๋๋ฆฌ๋ ๋ฐ๋ณต๋ฌธ์ด ์กด์ฌํ๊ธฐ ์ด์ ์
๋ฐ๋ณต์ ๋๋ฆฌ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
const fruits = ['Apple', 'Banana', 'Cherry'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ๊ตฌํ๊ณ , ์ธ๋ฑ์ค๋ก ์ฌ์ฉํ ๋ณ์๋ฅผ ์์ฑํ ๋ค์, ๊ทธ ์ธ๋ฑ์ค๋ก ๋ฐฐ์ด์ ์ ๊ทผํ๋ ๊ฒ์ด๋ค. ์ด๋ฅผ for-i
๋ฐ๋ณต๋ฌธ์ด๋ผ ํ์.
๊ทธ๋ฐ๋ฐ ์ด์ฐจํผ ๋ฐฐ์ด์ ๋๋ฆฌ๋ ๋ชฉ์ ์์ฒด๊ฐ ๋ฐฐ์ด์ ์์ดํ
์ ๊ฐ์ง๊ณ ๋ฌด์ธ๊ฐ๋ฅผ ํ๊ธฐ ์ํจ์ด์ง ์์๊ฐ? ๊ทธ๋์ ๋ง์ ์ธ์ด๋ค์ ๋ฐฐ์ด์ ํ์
์
์ํ ๊ฐ๋ฅํ ์ด๋ค ํ๋กํ ์ฝ์ ๋ฐ๋ฅด๋๋ก ์ ํฉ์ฑ์ ์ถ๊ฐํ๊ณ , ์ด๊ฑธ ์ด์ฉํด ๋ฐ๋ก ์์ดํ
์ ๊บผ๋ด์ค๋๋ก ํ๋ ๋ฐ๋ณต๋ฌธ์ด ์๊ฒผ๋ค.
JavaScript ์์ ์ด๊ฒ์ด ๋ฐ๋ก for-of
๋ค.
MDN - forโฆof ๋ฅผ ๋ณด๋ฉด Iterable Objects
๋ฅผ ๋ฐ๋ณตํ ์ ์๋ค๊ณ ์ค๋ช
ํ๋ค. ์ด๊ฒ์ ๋ค๋ฅธ ์ธ์ด์ ๋ง์ฐฌ๊ฐ์ง๋ก Iterable ํ๋กํ ์ฝ์
์ค์ํ๋ ๋ฐ์ดํฐ ํ์
์ ์๋ฏธํ๋ค. JavaScript ์์ ์ด๊ฒ์ Iteration Protocols
๋ฅผ ์ค์ํ๋ Types ๋ฅผ ์๋ฏธํ๋ฉฐ, ์ด๊ฒ์ ๋ ๊ฐ์ ํ๋กํ ์ฝ์ ์๋ฏธํ๋ค.
Iteration Protocols
- Iterable Protocol:
@@iterator
์ฌ๋ณผ๋ก ์๋ ค์ง[Symbol.iterator]
๋ฉ์๋๋ฅผ ๊ตฌํํ ๋ฐ์ดํฐ ํ์ ์ผ๋ก Array, Map ๋ฑ์ด ํด๋นํ๋ค. - Iterator Protocol:
Iterator.prototype
์ ์์ํดthis
๋ฅผ ๋ฐํํ๋[@@iterator]()
๋ฉ์๋๋ฅผ ๊ตฌํํ ๋ฐ์ดํฐ ํ์ ์ผ๋ก Generator Object ๊ฐ ํด๋นํ๋ค.
๋ชจ๋ ๊ฐ์ฒด๋ Iteration Protocols ๋ฅผ ๋ฐ๋ฅด๋๋ก ํ ์ ์์ผ๋ฉฐ, ๋ค์์ Iterable Protocol ๊ณผ Iterator Protocol ์ ๋ชจ๋ ๋ง์กฑ์ํค๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ๋๋ค.
// Satisfies both the Iterator Protocol and Iterable
const myIterator = {
next() {
// ...
},
[Symbol.iterator]() {
return this;
},
};
์ด ๋ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ๊ทธ ๊ฐ์ฒด๋ Iteration Protocols
๋ฅผ ์ค์ํ๊ฒ ๋๋ค.
JavaScript ์์ Iteration Protocols ๋ฅผ ์ค์ํ๋ Iterable Objects ๋ Array, String, TypedArray, Map, Set,
NodeList(and other DOM collections), arguments, Generator Functions, User-Defined Iterablesโฆ ์ ์๋ฏธํ๋ค.
์ด๊ฒ์ด ๋ฐ๋ก ์ผ๋ฐ์ ์ผ๋ก ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ for
๋ฐ๋ณต๋ฌธ์ ๋๋ฆฌ๋ ๋ฐฉ๋ฒ์ด๊ณ , JavaScript ์ for
๋ฐ๋ณต๋ฌธ์ ๋๋ฆฌ๋ ๋ฐฉ๋ฒ์ด๋ค.
Iteration Protocols
๋ฅผ ์ค์ํ๋ ๋ฐ์ดํฐ Types ๋ for-of
๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ ์ ์๋ค.
for (const fruit of fruits) {
console.log(fruit);
}
4. for-in
for-of ์์ ์ ์ ์๋ ๊ฒ์, Map
, Set
์ for-of
๋ฅผ ์ฌ์ฉํด ๋ฐ๋ณต์ ๋๋ฆด ์ ์๋๋ฐ, ์ฌ๊ธฐ์ Object
๊ฐ
๋น ์ก๋ค๋ ๊ฒ์ด๋ค. JavaScript ๋ ํจ์๋ Function Objects ์ผ ์ ๋๋ก ๋ชจ๋ ๊ฒ์ด Object
๊ธฐ๋ฐ์ด๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋
Object
๋ Iteration Protocols ๋ฅผ ๋ฐ๋ฅด์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
const fruits = {
Apple: 4200,
Banana: 6800,
Cherry: 3400,
};
for (const fruit of fruits) { // Uncaught TypeError: fruits is not iterable
console.log(fruit);
}
๊ทธ๋ ๋ค๋ฉด Object
๋ ์ด๋ป๊ฒ ๋ฐ๋ณต์ ๋๋ ค์ผ ํ ๊น? for-i
๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ ๊ทผํ ์ ์๋ค.
for (let i = 0, keys = Object.keys(fruits); i < keys.length; i++) {
console.log(keys[i], fruits[keys[i]]);
}
Object
์ prototype ์ keys
๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ชจ๋ ํค๋ฅผ ์ถ์ถํด์ ๋ฐฐ์ด๋ก ๋ง๋ค๊ณ , ์ด๊ฒ์ ์ด์ฉํด ์ ๊ทผํ๋ ๊ฒ์ด๋ค.
for-i
๋ณด๋ค for-of ๊ฐ ๊ฐ๋
์ฑ์ ๋ฌผ๋ก ์ด๊ณ ์ฌ์ฉํ๊ธฐ ๋ ํธํ ๊ฒ ๊ฐ์๋ฐ ๋ฐฉ๋ฒ์ด ์์๊น?
for (const [key, value] of Object.entries(fruits)) {
console.log(key, value);
}
Object
์ prototype ์ entries
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด, [key, value]
Tuple ํ์
์ ๋ฐฐ์ด์ ๋ฐํํ๋ค(์๋ฐํ ๋งํ๋ฉด
TypeScript ๊ฐ ์๋ JavaScript ์์ ์ด๊ฒ์ ๋ฐฐ์ด์ด๊ณ , ์ด์ค ๋ฐฐ์ด์ ํด๋นํ๋ค). ์ด๊ฒ์ ์ด์ฉํด ์ ๊ทผํ๋ ๊ฒ์ด๋ค.
๋ฌผ๋ก , forEach
๋ฅผ ์ฌ์ฉํ๋ฉด
Object.keys(fruits).forEach((key) => console.log(key, fruits[key]));
Object.values(fruits).forEach((value) => console.log(value));
Object.entries(fruits).forEach(([key, value] = user) => console.log(key, value));
์ ๊ฐ์ด ์ ๊ทผํ ์๋ ์์ง๋ง, for-of ๋ฅผ ํตํ ์ ๊ทผ ๋ฐฉ๋ฒ๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์์ ๋ฟ๋๋ฌ, break
์ ๊ฐ์
Control Flow ๋ฅผ ํ ์ ์๋ค๋ ๋ฌธ์ ๊ฐ ์๋ค.
๊ทธ๋์ ๋์จ ๊ฒ์ด for-in
๋ฐ๋ณต๋ฌธ์ด๋ค. MDN - forโฆin ๋ฅผ ๋ณด๋ฉด Symbols
๋ฅผ ์ ์ธํ ๋ชจ๋ enumerable string properties
๋ฅผ ๋ฐ๋ณตํ ์ ์๋ค๊ณ ์ค๋ช
ํ๋ค.
์ด ์ด๊ฑฐ ๊ฐ๋ฅํ ๋ฌธ์์ด ์์ฑ(enumerable string properties)
์ด๋ ๋ค์์ ์๋ฏธํ๋ค.
const obj = {};
Object.defineProperty(obj, 'Apple', {
value: 4200,
enumerable: true // default, true
});
Object.keys
, Object.values
, Object.entries
๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ ๋ฌธ์์ด properties ๋ฅผ ์๋ฏธํ๋ค. ๊ฒฐ๊ตญ
Object
๋ฅผ ์ํด ์กด์ฌํ๋ ๋ฐ๋ณต๋ฌธ์ด๋ผ๋ ๋ง์ด๋ค.
for (const fruit in fruits) {
console.log(fruit, fruits[fruit]);
}
5. What is the problem?
Iteration Protocols
๋ฅผ ์ค์ํ๋ Types ๋ for-of ๋ฅผ ์ฌ์ฉํ๊ณ , ์ด๋ฅผ ๋ฐ๋ฅด์ง ์๋ Object
๋
for-in ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ๊ทธ๋ฐ๋ฐ ๋ฌด์์ด ๋ฌธ์ ์ผ๊น? ์ ๋
ผ๋์ด ์๋ ๊ฒ์ผ๊น?
์ด๊ฒ์ JavaScript ์ ๊ตฌ์กฐ์ ์ธ ๋ฌธ์ ๋๋ฌธ์ด๋ค. JavaScript ๋ ๋ค๋ฅธ ์ธ์ด์ ๋ฌ๋ฆฌ Arrays ์ญ์ Objects ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
const fruits = ['Apple', 'Banana', 'Cherry'];
for (const fruit in fruits) {
console.log(fruit, fruits[fruit]);
}
์ฆ, Objects ๋ฅผ ์ํด ์กด์ฌํ๋ ๋ฐ๋ณต๋ฌธ์ธ๋ฐ, Arrays ์ ์คํ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค(์ฐธ๊ณ ๋ก Map ์ ๋์ผํ๊ฒ Key-Value
Types ์ง๋ง
Iteration Protocols
๋ฅผ ์ค์ํ๊ธฐ ๋๋ฌธ์ for-of
๋ฐ๋ณต๋ฌธ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค).
ย | for-of(Iteration Protocols) | for-in(enumerable string properties) |
---|---|---|
Objects | X | O |
Arrays | O | O |
Map | O | X |
ํ๋ก ๋ณด๋ฉด ํ ๋์ ๋ฌด์์ด ๋ฌธ์ ์ธ์ง ์ ์ ์๋ค. Arrays ์ ์ค์ ๋ก for-of
์ for-in
์ด ๋ชจ๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ๊ฒ์ด๋ค.
const fruits = ['Apple', 'Banana', 'Cherry'];
for (const fruit in fruits) {
console.log(fruit, fruits[fruit]);
}
0 Apple
1 Banana
2 Cherry
๋ฌผ๋ก ์ด๋ฐ์์ผ๋ก index
๋ฅผ Key ๋ก ํ๋ Key-Value
Types ํํ์ Objects ๋ก ์ธ์๋์ง๋ง ๋ง์ด๋ค.
๋น ๋ฅด๊ฒ ๋ฐ๋ณตํ ์ ์๋๋ก ๋ง๋ค์ด ๋์ ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ง ์๊ณ
๊ตณ์ด for-in
์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ฆฐ ๊ฒ์ด๋ค.
2. Performance Test ๐ฉโ๐ป
for-in ์ด ๋๋ฆฐ ๊ฒ์ด ์๋๋ผ ์๋ชป ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ฆฐ ๊ฒ์ด๋ผ๊ณ
์์์ ์ค๋ช
ํ๋ค. ๋ฐ๋ณต์ ์ํด Iteration Protocols
์ ๋ง๋ค๊ณ , ์ด๊ฒ์ ์ฌ์ฉํ๋ for-of
๋ฅผ ๋ง๋ค์ด ๋จ๋๋ฐ
Iteration Protocols
๋ฅผ ์ง์ํ๋ ๋ฐฐ์ด์ ๊ตณ์ด for-of
๋ฅผ ์ฌ์ฉํ์ง ์๊ณ for-in
์ ์ฌ์ฉํ๋ ๋๋ฆฐ ๊ฒ์ด๋ค.
๊ทธ๋ ๋ค๋ฉด for-in ์ ๋ชฉ์ ์ ๋ง๊ฒ Objects
์ ์ฌ์ฉํด๋ ์ ๋ง๋ก for-in ๋ณด๋ค ๋๋ฆด๊น?
๋ค์ ํจ์๋ ์ฃผ์ด์ง ๊ธธ์ด์ ๋ง๊ฒ properties ๋ฅผ 1๋ถํฐ ์์ฑํ๋ค.
function LargeObject(length) {
for (let i = 1; i <= length; i++) {
this[i] = i;
}
}
์๋ฅผ ๋ค์ด
const obj = new LargeObject(10);
๋ {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}
๋ฅผ ์์ฑํ๊ณ , ๋ชจ๋ values ๋ฅผ ํฉํ๋ฉด 1~10 ์
๋ฑ์ฐจ์์ด์ ํฉ์ ์ป์ ์ ์๋ค. ์ด๋ฅผ ์ด์ฉํด 1~5000๋ง์ ๋ฑ์ฐจ์์ด์ ํฉ์ ๊ตฌํด๋ณด์.
1. for-i
let t1 = performance.now();
let result = 0;
for (let i = 0, keys = Object.keys(obj); i < keys.length; i++) {
result += obj[keys[i]];
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(13.6785 + 13.9869 + 13.9156 + 13.6352 + 13.5382) / 5 = 13.7509s
2. for-in
let t1 = performance.now();
let result = 0;
for (const key in obj) {
result += obj[key];
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(16.2790 + 16.1625 + 15.5917 + 16.2225 + 15.9502) / 5 = 16.0412s
3. for-of
- Object.entries
let t1 = performance.now();
let result = 0;
for (const [key, value] of Object.entries(obj)) {
result += value;
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
97.4734s ์ด๊ฑด ๋ญ ์ถ๊ฐ๋ก ํ์ธํด๋ณผ ํ์๋ ์์ ์ ๋๋ก ๋๋ฆฌ๋ค.
๊ทธ๋ ๋ค๋ฉด Object.entries
๊ฐ ์๋ Object.keys
๋๋ Object.values
๋ก ์ ๊ทผํด๋ณด๋ฉด ์ด๋จ๊น?
- Object.keys
let t1 = performance.now();
let result = 0;
for (const key of Object.keys(obj)) {
result += obj[key];
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(13.2539 + 13.3760 + 14.1827 + 13.6154 + 13.2166) / 5 = 13.5289s
์ฌ์ค์ for-i
์ ๊ฐ์ ๋ก์ง์ผ๋ก ๋ด๋ ๋๋ค๋ณด๋ ์ฑ๋ฅ ์ญ์ ๋์ผํ๊ฒ ํ์ธ๋๋ค.
- Object.values
let t1 = performance.now();
let result = 0;
for (const value of Object.values(obj)) {
result += value;
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(0.4228 + 0.4267 + 0.4233 + 0.4990 + 0.4860) / 5 = 0.4516s
4. forEach & reduce
- forEach
let t1 = performance.now();
let result = 0;
Object.keys(obj).forEach((key) => (result += obj[key]));
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(14.2790 + 13.3194 + 12.9647 + 13.5687 + 13.4019) / 5 = 13.5067s
for-of
๋, for-in
์ด๋ ๋ณด๋ค๋ ์ฌ์ค์ Object.keys
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋๊ฐ? Object.values
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋๊ฐ?
Object.entries
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋๊ฐ๊ฐ ์ค์ํ๋ค๋ ๊ฒ์ ํ์ธํ๋ค. ๊ทธ๋ ๋ค๋ฉด ๋น์ฐํ๊ฒ๋ forEach
๋ฅผ ์ฌ์ฉํด๋ ์ด ์กฐ๊ฑด์
๋์ผํ ๊ฒ์ด๋ค. ์ด๋ฒ์๋ Object.values
๋ฅผ ์ฌ์ฉํด ๋ค์ ๋ฐ๋ณต์ ๋๋ ค๋ณด์.
let t1 = performance.now();
let result = 0;
Object.values(obj).forEach((value) => (result += value));
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(0.6285 + 0.6105 + 0.7024 + 0.7003 + 0.7266) / 5 = 0.6737s
- reduce
Object.values
๋ก ๋ฐฐ์ด์ ๋ง๋ ๋ค์ for-of
๋ฅผ ์ฌ์ฉํ ๊ฒ๋ณด๋ค ๋ฏธ์ธํ๊ฒ ๋๋ฆฌ์ง๋ง, ๋ค๋ฅธ ๋ฐฉ๋ฒ๊ณผ๋ ๋น๊ตํ ์ ์์ ๋งํผ ๋น ๋ฅด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ข ๋ ์์ ํจ์๊ฐ ๋๋๋ก ์ธ๋ถ์์ ์ํธ์์ฉ์ ์์ ํ ์ฐจ๋จ์์ผ reduce
๋ฅผ ์ ์ฉ์์ผ๋ณด์.
let t1 = performance.now();
const result = Object.values(obj).reduce((acc, cur) => acc + cur, 0);
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(0.4886 + 0.4565 + 0.4839 + 0.4827 + 0.5215) / 5 = 0.4866s
Object.values
๋ก ๋ฐฐ์ด์ ๋ง๋ ๋ค์ for-of
๋ฅผ ์ฌ์ฉํ ๊ฒ๊ณผ ์ฐจ์ด๊ฐ ์๋ค.
5. while
let t1 = performance.now();
let result = 0;
let i = 0;
const keys = Object.keys(obj);
while (i < keys.length) {
result += obj[keys[i]];
i++;
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(13.5255 + 13.7702 + 13.7690 + 13.2951 + 13.2285) / 5 = 13.5177s
๋ง์ฐฌ๊ฐ์ง๋ก Object.values
๋ฅผ ์ฌ์ฉํด ๋ค์ ๋ฐ๋ณต์ ๋๋ ค๋ณด์.
let t1 = performance.now();
let result = 0;
let i = 0;
const values = Object.keys(obj);
while (i < values.length) {
result += values[i];
i++;
}
console.log(`Sum: ${result}, ${result === 1_250_000_025_000_000}`);
let t2 = performance.now();
console.log(`Time Elapsed: ${(t2 - t1) / 1000} seconds.`);
(0.2336 + 0.1520 + 0.2443 + 0.2490 + 0.2424) / 5 = 0.2243s
์ฐธ๊ณ ๋ก for-i
์ญ์ Object.values
๋ฅผ ์ฌ์ฉํด์ ๋ฐฐ์ด์ ๋๋ฆฌ๋ฉด while
๊ณผ ๋์ผํ ์ฑ๋ฅ์ด ์ธก์ ๋๋ค.
6 Summary
ํ
์คํธ ๊ฒฐ๊ณผ๋ฅผ ํ๋ก ์ ๋ฆฌํด๋ณด์. ์ฐ์ for-in
์ ์ ์ธํ ๋ชจ๋ ๋ฐฉ๋ฒ์ ๋ฐ๋ณต์ ๋๋ฆฌ๊ธฐ ์ํด์๋ Object.entries
, Object.keys
,
Object.values
๋ฉ์๋ ์ค ํ๋๋ฅผ ์ฌ์ฉํด์ผํ๋๋ฐ, ์ด ๋ฉ์๋์ ๋ฐ๋ฅธ ํธ์ฐจ๊ฐ ๋งค์ฐ ํฌ๋ค.
for-of | ||
---|---|---|
Object.entries | Object.keys | Object.values |
97.4734s | 13.5289s | 0.4516s |
์ด ๊ฒฐ๊ณผ๋ง ๋๊ณ ๋ณด๋ฉด ๋ฌด์กฐ๊ฑด Object.values
๋ฅผ ์ฌ์ฉํด์ผ๋ง ํ ๊ฒ ๊ฐ๋ค. ํ์ง๋ง ์ฌ๊ธฐ์ ์น๋ช
์ ์ธ ๋ฌธ์ ์ ์ด ์กด์ฌํ๋ค.
const fruits = {
Apple: 4200,
Apricot: 9200,
Avocado: 10300,
Banana: 6800,
Blueberry: 9700,
Blackberry: 8300,
Cherry: 3400,
Clementine: 7700,
Cranberry: 6900,
...
Grape: 3700,
Guava: 7100,
Gooseberry: 8100,
...
}
์ fruits
๊ฐ์ฒด์ ๋ชจ๋ ๊ณผ์ผ ๊ฐ๊ฒฉ์ ํ๊ท ์ ๊ตฌํด์ผ ํ ๊ฒฝ์ฐ๋ Object.values
๋ฅผ ์ฌ์ฉํ๋ฉด ๋งค์ฐ ๋น ๋ฅผ ๊ฒ์ด๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ
Key-Value
Types ๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋, key ์ value ์ ์ฐ๊ด์ฑ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ง์ฝ ์ํ๋ฒณ โBโ๋ก ์์ํ๋ ๊ณผ์ผ์
ํ๊ท ๊ฐ๊ฒฉ์ ๊ตฌํด์ผ ํ ๊ฒฝ์ฐ์ ๊ฐ์ ์ํฉ์์ Object.values
๋ ์ฌ์ฉํ ์ ์๋ค. ๋ชจ๋ ๊ฐ์ ์ผ๋จ ๋ฐฐ์ด๋ก ๋ง๋ค๊ณ ๋ฐ๋ณต์ ๋๋ฆฌ๊ธฐ
๋๋ฌธ์ for-of
๋ ๋ฌผ๋ก ์ด๊ณ , for-i
, while
์ ๊ฐ์ ๋ชจ๋ ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ ์ ์๊ณ ๋น ๋ฅด์ง๋ง ์ด๊ฑด ๊ทธ์ Values ์ ๋ฐฐ์ด์
์ถ์ถํ ๋ค์ ๋ฐฐ์ด์ ๋ฐ๋ณต๋ฌธ ๋๋ฆฌ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ์ด ์๋๋ค.
for-i (Object.keys) | 13.7509s |
---|---|
for-in | 16.0412s |
for-of (Object.keys) | 13.5289s |
forEach (Object.keys) | 13.5067s |
while (Object.keys) | 13.5177s |
key
๊ฐ ํ์ํ ์ํฉ์์ ์ญ์ for-in
์ด ์กฐ๊ธ ๋๋ฆฌ๊ธด ํ๋ค. ํ์ง๋ง ์ด๊ฒ์ ํ
์คํธ๋ฅผ ์ํด ํ ๊ฐ์ฒด ์์ properties ๋ฅผ
5000๋ง๊ฐ๋ ์์ฑํ ๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ๋ผ๋ ๊ฒ์ ๊ณ ๋ คํด์ผํ๋ค. ๋ฐฐ์ด๋ ์๋ ๋จ์ผ ๊ฐ์ฒด ๋ด์ properties ๋ฅผ 5000๋ง๊ฐ๋ ๋ง๋๋ ๊ฒฝ์ฐ๋
์๊ธฐ ๋๋ฌธ์ด๋ค. ํน์๋ผ๋ ์ด๋ฐ ์ํฉ์ด ์กด์ฌํ๋ค๋ฉด, ์ค๊ณ๋ถํฐ ์ฌ๊ฐํ๊ฒ ์๋ชป ๋์ง ์์๋๋ฅผ ๊ณ ๋ฏผํด๋ด์ผ ํ๋ค. ์ด๋ ๊ฒ ๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ์ ์กฐ์ฐจ
18% ์ ๋ ์ฐจ์ด์ผ ๋ฟ ์๋๋ผ ์ ๋์ ์์น๋ก๋ 1.5์ด ์ ๋ ์ฐจ์ด๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก ๋งํ์๋ฉด ํต์์ ์ธ ๋ฒ์ ๋ด์์ Object ๋ฅผ ๋ฐ๋ณตํ ๋ for-of
์ for-in
์
์๋ ์ฐจ์ด๋ ์๋ค๊ณ ํ ์ ์๋ค.
3. Final Conclusion ๐ฉโ๐ป
- Arrays ์ ๊ฐ์ด Iteration Protocols ๋ฅผ ์ง์ํ๋ Types ๋
for-of
๋๋forEach
๋ฅผ ์ฌ์ฉํด๋ผ(๋ฐฐ์ด์ด ๋งค์ฐ ํด ๊ฒฝ์ฐ๋for-i
์while
์ดfor-of
๋forEach
๋ณด๋ค ์กฐ๊ธ ๋น ๋ฅด๊ธด ํ๋ค). - Objects ์ Keys ๋ ํ์ํ์ง ์์ผ๋ฉฐ, ๋ชจ๋ Values ๋ฅผ ๋์์ผ๋ก ๋ฐ๋ณต์ ํด์ผํ ๊ฒฝ์ฐ๋
Object.values
๋ฉ์๋๋ฅผ ์ฌ์ฉํด๋ผ. - Objects ์ Keys ๊ฐ ํ์ํ ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ ๋๋
for-in
์ ๊ฒฐ์ฝ ๋๋ฆฌ์ง ์๋ค. ํธ๋ฆฌํ๋ค! ๊ทธ๋ฌ๋ฏ๋กfor-in
์ ์จ๋ผ!
Reference
- โforโฆin.โ MDN Web Docs. Sep. 25, 2023, accessed Apr. 09, 2024, MDN - forโฆin.
- โforโฆof.โ MDN Web Docs. Aug. 25, 2023, accessed Apr. 09, 2024, MDN - forโฆof.
- โIteration protocols.โ MDN Web Docs. Dec. 27, 2023, accessed Apr. 09, 2024, MDN - Iteration protocols.