JavaScript로 문자열 뒤집기

문자열 뒤집기란 주어진 문자열의 순서를 뒤바꾸는 것이다. 예를들어서 'AFX'이라는 문자열을 넣으면 'XFA'가 나온다.

간단해보이지만 여러가지 방법으로 구현해볼 수 있다. C로 구현한다면 문자열 처음과 끝에서 커서(문자열 포인터) 두 개를 놓고 가운데를 향해 가면서 각 문자를 맞바꾸는 것으로 구현할 수 있다.

문득 갑자기 JavaScript에 있는 Array.prototype.reverse와 직접 swap하는 건 얼마나 다를까 궁금해져서 테스트를 해봤다.

const test = 'We are the music-makers, And we are the dreamers of dreams.';

console.time('Array.prototype.reverse');
console.log(Array.from(test).reverse().join(''));
console.timeEnd('Array.prototype.reverse');

console.time('Swap');
const arr = Array.from(test);
let tmp;
for (let i = 0, j = test.length - 1; i < j; ++i, --j) {
  tmp = arr[i];
  arr[i] = arr[j];
  arr[j] = tmp;
}
console.log(arr.join(''));
console.timeEnd('Swap');

내 컴퓨터에서 실행해본 결과는 다음과 같았다.

.smaerd fo sremaerd eht era ew dnA ,srekam-cisum eht era eW
Array.prototype.reverse: 3.617ms
.smaerd fo sremaerd eht era ew dnA ,srekam-cisum eht era eW
Swap: 0.187ms

단순히 O(N)과 O(N/2)의 차이라면 그다지 속도차이가 나지 않을 것이다. 궁금해서 Node.js와 v8의 코드를 검색해보니 v8Array.prototype.reverse가 정의되어있지만 아직 잘 모르겠다. 내부적으로 구현된 reverse함수가 느린 것인가?

추가: 나는 단순히 Swapping이 빠르다고 결론지었는데, 위 두 코드를 순서를 바꾸어서 실행해보면 정반대의 결과가 나온다. 아마도 Array.from(test)에서 배열을 재활용을 하고 있는게 아닌가 싶다. 애초에 한 프로그램에서 두 경우를 순차적으로 실행한 것이 잘못된 것이다. 각각의 경우를 독립적으로 실행하면 다음과 같이 나온다.

Swap: 29.182ms
...
Array.prototype.reverse: 19.196ms

결론: Array.prototype.reverse는 최적화가 잘 되어있습니다. (:sweat:)