JavaScript ์ sort ํจ์๋ ์์ ์ ๋ ฌ์ผ๊น?
๐ ์์ ์ ๋ ฌ์ด๋?
์์ ์ ๋ ฌ(stable sort) ์ ๋์ผํ ํค ๊ฐ์ ๋ํด ์
๋ ฅ ์์๋ฅผ ๋ณด์ฅํ๋ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์
๋๋ค.
๊ทธ ๋ฐ๋์ธ ๋ถ์์ ์ ๋ ฌ(unstable sort) ์ ์ ๋ ฌ ํ ์
๋ ฅ ์์๋ฅผ ๋ณด์ฅํด์ฃผ์ง ์์ต๋๋ค.
๋ํ์ ์ธ ์์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์ด 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
1๏ธโฃ ๋ฒ๋ธ ์ ๋ ฌ (Bubble Sort)

2๏ธโฃ ์ฝ์ ์ ๋ ฌ (Insertion Sort)

3๏ธโฃ ๋ณํฉ ์ ๋ ฌ (Merge Sort)

๊ทธ ์ธ ํต ์ ๋ ฌ ๊ณผ ์ ํ ์ ๋ ฌ ์ ๋ถ์์ ์ ๋ ฌ ์ ๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์
๋๋ค.
๐ JavaScript ์ sort ํจ์
JavaScript ์ sort ํจ์๋ ์์ ์ ๋ ฌ์ผ๊น?
JavaScript ์ sort ํจ์๋ ๊ทธ๋ ๋ค๋ฉด ์์ ์ ๋ ฌ ์ผ๊น์?
Chrome 70 ๋ฒ์ ์ด์ ์์๋ ์ฌ์ค JavaScript ์ ๊ตฌํ ์คํ์ ์์ ์ ๋ ฌ์ ๊ฐ์ํ์ง ์์๋ค๊ณ ํฉ๋๋ค.
๋๋ฌธ์ ๊ฐ๊ฐ์ ์์ง ๊ตฌํ์ฒด๋ง๋ค ์ ๋ ฌ ๋ฐฉ์์ด ๋ค๋ฅด๊ฒ ๋์ด์์ผ๋ฉฐ chrome ์ ๊ฒฝ์ฐ์๋ ๋ฐฐ์ด์ ๊ธธ์ด์ ๋ฐ๋ผ
์์ ์ ๋ ฌ์ผ ์๋ ์๊ณ ๋ถ์์ ์ ๋ ฌ์ผ ์๋ ์์๋ค๊ณ ํฉ๋๋ค.
ํ์ง๋ง chrome 70 ์ดํ ๋ฒ์ ๋ถํฐ๋ Array.sort ๋ฅผ ์์ ์ ๋ ฌ๋ก ๊ตฌํํ๋๋ก ์คํ์ด ์ง์ ๋์๊ณ
๊ทธ์ ๋ฐ๋ผ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ์์ ์ ๋ ฌ์์ ๋ณด์ฅํ ์ ์๊ฒ ๋์๋ค๊ณ ํฉ๋๋ค.
Chrome 70 ์ด์ ์์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ
๋ค์์ chrome 70 ์ด์ ์ V8 ์์ง ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ ์์ค์ฝ๋์
๋๋ค.
// v8/array.js
/**
* โ
Array.prototype.sort ๋ฅผ ์ ์ํฉ๋๋ค.
*/
DEFINE_METHOD(
GlobalArray.prototype,
sort(comparefn) {
if (!IS_UNDEFINED(comparefn) && !IS_CALLABLE(comparefn)) {
throw %make_type_error(kBadSortComparisonFunction, comparefn);
}
var array = TO_OBJECT(this);
var length = TO_LENGTH(array.length);
return InnerArraySort(array, length, comparefn);
}
);
/**
* โ
์ค์ ์ ๋ ฌ์ ์ํํ๋ ํจ์์
๋๋ค.
*/
function InnerArraySort(array, length, comparefn) {
// In-place QuickSort algorithm.
// For short (length <= 10) arrays, insertion sort is used for efficiency.
if (!IS_CALLABLE(comparefn)) {
comparefn = /** ๊ธฐ๋ณธ ๋น๊ต ํจ์ ํ ๋น */
}
function InsertionSort(a, from, to) {/** */};
function QuickSort(a, from, to) {
// ...
while (true) {
// Insertion sort is faster for short arrays.
if (to - from <= 10) {
InsertionSort(a, from, to);
return;
}
// ...
};
if (length < 2) return array;
QuickSort(array, 0, num_non_undefined);
return array;
}
์ฝ๋๋ฅผ ๋ณด๋ฉด Array.prototype.sort ๋ ์์ง ๋ด๋ถ์ ์ผ๋ก InnerArraySort ํจ์๋ฅผ ํธ์ถํ๊ณ
ํด๋น ํจ์ ๋ด์์ ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ 10 ๋ณด๋ค ์์ ๊ฒฝ์ฐ์๋ Insertion Sort ๋ฅผ ์ฌ์ฉํ๊ณ
๊ทธ ์ธ์๋ Quick Sort ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ดํ์ v8 ์์ง์ Timsort ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ ์ ๋ ฌํฉ๋๋ค
stable ํจ์ ๋ณด์ฅํ๊ธฐ ์ํด์ ํ์ฌ v8 ์์ง์ TimSort ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด ์ ๋ ฌ์ ์ํํฉ๋๋ค.
๋ค์์ ํ์ฌ v8 ์์ง ์์ค์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ ์ฝ๋์
๋๋ค.
ArrayTimSort ๋ฅผ ํธ์ถํด์ stable ํ ์ ๋ ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
// third_party/v8/builtins/array-sort.tq
ArrayPrototypeSort(
js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
// ...
if (len < 2) return obj;
const sortState: SortState = NewSortState(obj, comparefn, len);
ArrayTimSort(context, sortState);
return obj;
}
๐ Chrome 70 ์ด์ ์ ์์ ์ ๋ ฌ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ
์์ ์ ๋ ฌ์ ๊ตฌํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๊ฐ ๋ฐฐ์ด ์์์ key ๊ฐ์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ง์ ํ๋ ๊ฒ์
๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๋ ๋ฐฐ์ด ์์์ ๋น๊ต ํค๊ฐ์ด ๋์ผํ ๊ฒฝ์ฐ์๋ ์ธ๋ฑ์ค๋ก ๋น๊ตํ๊ธฐ ๋๋ฌธ์ ์์๋ฅผ ๋ณด์ฅํ ์ ์์ต๋๋ค.
const stableSort = (arr, compare) =>
arr
.map((item, index) => ({ item, index }))
.sort((a, b) => compare(a.item, b.item) || a.index - b.index)
.map(({ item }) => item)
์ ํจ์๋ฅผ ์ด์ฉํด์ ์ ๋ ฌ์ ์ํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
/** โ
rating ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ์ ์ํํฉ๋๋ค. */
console.log(
stableSort(
[
{ name: "Abby", rating: 12 },
{ name: "Bandit", rating: 13 },
{ name: "Choco", rating: 14 },
{ name: "Daisy", rating: 12 },
{ name: "Elmo", rating: 12 },
{ name: "Falco", rating: 13 },
{ name: "Ghost", rating: 14 },
],
(a, b) => a.rating - b.rating
)
)[
/** ๊ทธ๋ฌ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ ๋ ฌ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค. */
({ name: "Abby", rating: 12 },
{ name: "Daisy", rating: 12 },
{ name: "Elmo", rating: 12 },
{ name: "Bandit", rating: 13 },
{ name: "Falco", rating: 13 },
{ name: "Choco", rating: 14 },
{ name: "Ghost", rating: 14 })
]
๐ ์ฐธ๊ณ ์๋ฃ
'๐จโ๐ป web.dev > frontend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| React ์ค๋๋ ํด๋ก์ (Stale Closure) ์ด์ ํด๊ฒฐํ๊ธฐ (0) | 2022.05.11 |
|---|---|
| React ์ ์ด ์ปดํฌ๋ํธ vs ๋น์ ์ด ์ปดํฌ๋ํธ (0) | 2022.04.10 |
| [TypeScript] js.map ํ์ผ์ ๋ฌด์์ผ๊น? (0) | 2022.03.07 |
| [JavaScript] Object.defineProperty ์ ๋ํด์ (0) | 2022.03.06 |
| [JavaScript] Promise.all vs Promise.allSettled (0) | 2022.02.20 |
๐ฌ ๋๊ธ