[Javascript] Array์ ๊ตฌ์กฐ (V8)
์ฌ๊ธฐ์๋ V8์ ๋์๋ง ์ ๋ฆฌํ๋ค. ๋ธ๋ผ์ฐ์ ๋ง๋ค ๋์๋ฐฉ์์ด๋ ๊ตฌ์กฐ๋ ํฌ๊ฒ ๋ค๋ฅด๋ค.
Javascript์์์ Array๋ ๋ค๋ฅธ ์ธ์ด๋ค์ Array์ ํฌ๊ฒ ๋ค๋ฅด๋ค. ์์ํ ๋ฐฐ์ด์ด ์๋๋ผ Object์ ํ ์ข ๋ฅ๋ก์ ์ทจ๊ธ๋๊ธฐ ๋๋ฌธ์ด๋ค.
์์ ๊ฐ์ด Object๊ฐ ๋์
๋๋ฆฌ ํํ๋ฉด properties์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ , ํค๊ฐ ์ซ์์ธ ๋ฐฐ์ด ํํ๋ฉด elements์ ๊ฐ์ ์ ์ฅํ๋ค. elements์ ๊ฐ์ด ๋ค์ด์์ผ๋ฉด ์ด์ ๋ฐฐ์ด์ด ๋๋ ๊ฒ์ด๋ค.
๋ฐฐ์ด ํ์ ์ ํ
๋ฐฐ์ด์๋ ์๋ฌด ํ์ ์ด๋ ๋ง ๋ค์ด๊ฐ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง, ์ฌ์ค ๋ด๋ถ์ ์ผ๋ก๋ ๊ต์ฅํ ๋ณต์กํ ํ์ ๊ณผ ์ํ๋ฅผ ๋ณํ๋ฌด์ํ๊ฒ ์ค๊ฐ๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ์ ์๊ฐ์ ํฌํจํ๋ ๋ฐฐ์ด์ ์์ฑํ๋ฉด PACKED_SMI_ELEMENTS๋ผ๋ ๋ชจ๋๋ก ๋ฐฐ์ด์ด ๋ง๋ค์ด์ง๋ค.
const array = [1, 2, 3];
// elements kind: PACKED_SMI_ELEMENTS
SMI๋ ์์ ์ ์๋ฅผ ๋ปํ๋ ๋จ์ด์ธ๋ฐ, ๋ณดํต ์ด๊ฒ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์ต์ ํ๊ฐ ๋๋ค.
๋ฌผ๋ก JS๋ ๋์ ํ์ ์ธ์ด๊ณ , ์ธ์ ๋ ์ค์๋ ๋ฌธ์์ด ๊ฐ์ ๊ดด์๋ง์ธกํ ๊ฐ์ ๋ฃ์ ์๋ ์๋ค.
const array = [1, 2, 3];
// elements kind: PACKED_SMI_ELEMENTS
array.push(4.56);
// elements kind: PACKED_DOUBLE_ELEMENTS
array.push('x');
// elements kind: PACKED_ELEMENTS
ํ์
์ ์ผ๊ด์ฑ์ ์งํค์ง ๋ชปํ ๋๋ง๋ค ๋ ์ผ๋ฐ์ ์ธ ํํ์ ๋ฐฐ์ดํ์
์ผ๋ก ๋ณ๊ฒฝ์ด ๋๋ค.
๋น์ฐํ ๋ฐ์ผ๋ก ๊ฐ์๋ก ๋๋ ค์ง๋ค.
์ฌ๊ธฐ์ ์ ์ํ ์ ์ PACKED_ELEMENTS์ฒ๋ผ ์ผ๋ฐํ๋ ํ์ ์ผ๋ก ๋ด๋ ค์จ ๋ฐฐ์ด์, ๊ทธ๊ฑธ ๋ค์ ๋นผ๋๋ผ๋ PACKED_SMI_ELEMENTS๋ PACKED_DOUBLE_ELEMENTS ๊ฐ์ ๋ณด๋ค ๋น ๋ฅธ ํ์ ์ผ๋ก ๋์์ค์ง ๋ชปํ๋ค๋ ๊ฒ์ด๋ค. ๋๋๋ก์ด๋ฉด ํ์ ์ ์ผ๊ด์ฑ์ ์ง์ผ์ฃผ๋ ํธ์ด ์ข๋ค.
๊ตฌ๋ฉ ๋ซ๋ฆฐ ๋ฐฐ์ด (HOLEY)
JS์ ๋ฐฐ์ด์ ์ผ๋ฐ์ ์ธ ์ธ์ด๋ค์ ๋ฐฐ์ด ๊ตฌํ๊ณผ ๋ค๋ฅด๊ฒ, ์ธ๋ฑ์ค๋ฅผ ๊ฑด๋๋ฐ์ด์ ๊ฐ์ ํ ๋นํ๋ ์ด์ํ ์ง์ด ๊ฐ๋ฅํ๋ค.
const array = [1, 2, 3, 4.56, 'x'];
// elements kind: PACKED_ELEMENTS
array.length; // 5
array[9] = 1; // array[5] until array[8] are now holes
// elements kind: HOLEY_ELEMENTS
5 ์ธ๋ฑ์ค๋ฅผ ๊ฑด๋๋ฐ๊ณ 9 ์ธ๋ฑ์ค์ ๊ฐ์ ๋ฐ์์์๋ ๋๋๊ฒ๋ ์ ๋์ํ๋ค.
์ด๊ฑด ๋ด๋ถ์ ์ผ๋ก ์๋ก์ด ๋ฐฐ์ด์ ์์ฑํด์
์ค์ ๋ก ๊ธธ์ด๋ 10์ด ๋์๋ค. ์ค๊ฐ์ ์์๋ค์ ๊ตฌ๋ฉ(hole)์ด ๋ ๊ฒ์ด๋ค.
๊ตฌ๋ฉ ๋ฐฐ์ด(holey)๊ณผ ๋น๊ตํด์ ๊ตฌ๋ฉ์ด ์๋ ๋ฐฐ์ด์ PACKED๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, ๋น์ฐํ PACKED ๋ฐฐ์ด์ด ์ต์ ํ๊ฐ ํจ์ฌ ์ ๋๋ค.
์๋๋ ๋ฐฐ์ด ํ์ ์ด ๋ณ๊ฒฝ๋ ์ ์๋ ๋ฃจํธ๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ํํํ ๊ฒ์ด๋ค.
์ง๋์จ ๊ธธ์ ๋์์ฌ ์ ์๋ค.
๋ฐฐ์ด์ฒ๋ผ ์๊ธด ๊ฐ์ฒด
Javascript์์๋ ์ ์ด์ ๋ฐฐ์ด๊ณผ ๊ฐ์ฒด์ ๊ฒฝ๊ณ๊ฐ ํ๋ฆฟํ๋ค๋ณด๋ ๊ฐ์ฒด๋ก ์ด๊ธฐํํด์ ๋ฐฐ์ด์ฒ๋ผ ์ธ ์๋ ์๋ค.
const arrayLike = {};
arrayLike[0] = 'a';
arrayLike[1] = 'b';
arrayLike[2] = 'c';
arrayLike // { '0': 'a', '1': 'b', '2': 'c' }
์ด๊ฑด ์ฑ๋ฅ์ ๋ณ๋ก ์ข์ ์ฌ์ฉ๋ฒ์ ์๋๋ค. ๋ ๋๋ฆฐ Object ํํ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฐจ๋ผ๋ฆฌ ๋ฐฐ์ด์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
์กด์ฌํ์ง ์๋ ์์ ์ ๊ทผํ์ง ๋ง๊ธฐ
JS๋ ์.๊ฒฉ.ํ ๋ค๋ฅธ ์ธ์ด๋ค๊ณผ ๋ค๋ฅด๊ฒ ์กด์ฌํ์ง ์๋ ์์์ ์ ๊ทผํด๋ out of range ์ค๋ฅ๋ฅผ ๋ฑ์ง ์๋๋ค.
undefined๊ฐ ๋จ์ด์ง ๋ฟ์ด๋ค.
์ด๊ฒ๋ ์์ธ๋ก ์ฑ๋ฅ์ ์
์ํฅ์ ์ค ์ ์๋ ๋ถ๋ถ์ด๋ค.
๋ด๋ถ์ ์ผ๋ก properties๊น์ง ์ฐธ์กฐํด์ ์ ๊ฒ ์๋์ง ์๋์ง๋ฅผ ๊ฒ์ฌํ๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค. ์ฌ์ง์ด ์ ์ํฅ์ ํ๋ฐ์ ์ธ๊ฒ๋ ์๋๋ค.
V8์ ์ ๋ฐฐ์ด์ ๋ํด์ ํน์ํ ์ ๊ทผ์ ํ ์ ์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ๊ณ ๋ญ๊ฐ ๋ ๋๋ฆฐ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ๋๋ฌธ์, ์ ๋ฐฐ์ด ์์ฒด์ ๋ํ ์ ๊ทผ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ค.
๋ํ์ ์ผ๋ก ์ ์ด์ฟผ๋ฆฌ๊ฐ ์ด๋ฐ ์ํฐํจํด์ ์จ์
// Donโt do this!
for (let i = 0, item; (item = items[i]) != null; i++) {
doSomething(item);
}
์ฑ๋ฅ์ด ๋๋ฆฐ ๋ถ๋ถ์ด ์์๋ค๊ณ ํ๋ค. ์ ๋ฌ์ง๋ ๋ง์.
Array() ํจ์๋ก ๋ฐฐ์ด ์์ฑ
์ด๊ฑด ์ด๊ฒฌ์ด ์ข ๊ฐ๋ฆด ์๋ ์๋ ๋ถ๋ถ์ด๋ค.
Array ์์ฑ์ ํจ์๋ ๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ๋ฐ์์ ํด๋น ๊ธธ์ด์ ๋น ๋ฐฐ์ด์ ์์ฑํ ์ ์๋ค.
์ด๊ฑด push๋ฅผ ๋ฐ๋ณตํ ๋ ์๊ธฐ๋ ์๊ธฐ๋ growing ์์
์ด ๋ฐ์ํ์ง ์๊ธฐ ๋๋ฌธ์, ํ ๋น ์ฑ๋ฅ์ด ์ข๋ ๋ซ๊ณ ์ฌ์ด์ฆ๋ ๋ฑ ์ฌ๋ฆผํ๊ฒ ๋ง๋ค์ด์ง๋ค๋ ์ฅ์ ์ด ์๋ค.
ํ์ง๋ง ์ด ์์ฑ ๋ฐฉ์์ ๋ฐฐ์ด์ PACKED๊ฐ ์๋๋ผ HOLEY ๋ฐฐ์ด๋ก ์์ฑํ๋ค๋ ๋จ์ ๋ ๋์์ ์กด์ฌํ๋ค. ๊ณต๊ฐ์ ์๋ผ๊ธฐ ์ํด์์ธ ๊ฒ ๊ฐ๋ค.
ํ์ง๋ง V8 ๊ฐ๋ฐ์์ธ jmrk์ ์๊ฒฌ์ ๋ฐ๋ฅด๋ฉด ์ด์ฐจํผ packed์ holey์ ์ฑ๋ฅ ์ฐจ์ด๋ ๊ฑฐ์ ๋๋ผ๊ธฐ๊ฐ ์ด๋ ต๊ณ , push๋ฅผ ๋ฐ๋ณตํ๋ฉด์ ์ฆ๊ฐ์์ ๋ฐ์ํ๋ ์ฑ๋ฅ ๋ถํ๊ฐ ํจ์ฌ ์ปค์ ๊ทธ๋ฅ ์์ฑ ํจ์๋ฅผ ์ฐ๋ ๊ฒ์ ๊ถ์ฅํ๋ค๊ณ ํ๋ค.
์ฐธ์กฐ
https://v8.dev/blog/fast-properties?m=1
https://v8.dev/blog/elements-kinds
https://stackoverflow.com/questions/54481918/how-does-v8-optimise-the-creation-of-very-large-arrays