JavaScript와 C++: 문자열뒤집기

#기술

얼마 전부터 C++를 복습할 겸, 제대로 공부해보고자 C++ 언매니지드 프로그래밍 강의를 듣기 시작했다.

입/출력 스트림을 다루는 섹션에서 ‘문자열 뒤집기’ 예제가 나왔는데, 이 문제는 간단히 말해서 주어진 문자열의 순서를 뒤바꾸는 것이다. 'AFX'이라는 문자열을 넣으면 'XFA'가 나오는 식.

간단해보이지만 여러가지 방법으로 구현해볼 수 있다. JavaScript나 Python 같은 현대적인 언어를 알기 전인 대학생 강그루가 C로 이 문제를 푼다면 아마도 강의에서 제시한 예시처럼 포인터를 써서 문자열 처음과 끝에서 커서 두 개를 놓고 가운데를 향해 가면서 각 문자를 swap해주는 식으로 구현했을 것이다.

문득 갑자기 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[j];
  arr[j] = arr[i];
  arr[i] = tmp;
}
console.log(arr.join(''));
console.timeEnd('Swap');

단순히 O(N)과 O(N/2)의 차이라면 그다지 속도차이가 나지 않겠지 예상했다. 그리고 Swap에 해당하는 테스트는 변수도 여러 개 선언하고 있지 않은가. 하지만 내 macOS의 node v8.9.4로 실행해본 결과는 다음과 같았다.

.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

Swap의 압도적인 차이. 물론 이것 하나만 가지고 판단하기는 섣부르지만 생각보다 많이 차이나서 놀랐다. 그동안 TypeScript로 일을하면서 편리한 문법을 많이 썼는데, 뜨금해지는 순간이다.

궁금해서 Node.js와 v8의 코드를 검색해보니 v8Array.prototype.reverse가 정의되어있지만 아직 잘 모르겠다. C++를 공부하면 Node.js와 브라우저의 동작원리를 잘 이해할 수 있지 않을까 막연한 추측이 있었는데 이번 실험으로 조금은 확신이 생긴다.