블로그 내 검색

2013. 5. 15.

자바스크립트의 여러 정수 변환법과 성능

정수형 변환

자바스크립트 integer 형 정수형 변환은 native로 parseInt가 있다.
하지만 이 외에도, bit 연산자를 활용한 방법도 있고, 심지어 이쪽이 더욱 빠르다.

JavaScript의 정수형 변환에는 다음과 같은 방법이 쓰인다.
// 777.77 을 정수형으로 변환 시도
// 결과는 전부 10진 정수 [777]
parseInt(777.77, 10)
Math.floor(777.77)
~~777.77
777.77 | 0
777.77 >> 0
777.77 >>> 0
777.77 << 0
우연히 MDN에서 Array.indexOf의 구현을 보다가 구현 내용중에
var len = array.length >>> 0
이라는 구문이 있어서  '>>>' 의 정체가 뭘까 검색해보다가 정수형 변환법까지 거슬러 올라가게 되었다.

여러 검색 결과로 얻은 결론은,
만일 Int32 형 캐스팅이라면 bit 연산이 제일 빠르다는것(http://arnorhs.com/2012/05/30/comparing-the-performance-of-math-floor-parseint-and-a-bitwise-shift/)

제일 느린건 parseIntMath.floor 는 중간.
그런데 Math.floor는 -부호가 붙을 경우 -1 이 더해지므로 애매하다.

parseInt VS Bitwise

parseInt는 두번째 인자로 진법을 받아서 진법 변환도 해주므로 나름 쓸데가 있지만, 단순한 정수형 변환에는 bit 연산이 압도적으로 속도가 차이가 난다.

parseInt에 사족을 달면, 최근 브라우저들 스크립트 엔진에서는 parseInt 시 10진법을 기본값으로 사용하지만 구버전 스크립트는 10진법을 기본으로 사용하지 않고 첫번째 인자를 가지고 멋대로 판단하여 5진법이나 8진법으로 변환해주기도 했다.
// 진법 인자의 있고 없고 차이.
parseInt("0E0") // 0
parseInt("0E0", 10) // 0
parseInt("0E0", 16) // 224

// 두번째 인자가 없을때 해석의 차이.
// 구 브라우저 (ecmascript 3th -)
parseInt("08") // 0

// 모던 브라우저 (ecmascript 5th +)
parseInt("08") // 8

parseInt를 불가피하게 사용해야 한다면 무조건 진법 인자를 붙이는 습관을 들이자.

또 하나 사족을 달면,
Array.indexOf 구현에 사용된 number >>> 0 연산은 부호를 떼버린 unsigned 32int 를 반환한다.(http://ecma-international.org/ecma-262/5.1/#sec-11.7)

정수 변환에는 value >> 0 나 ~~value 이 제일 빠른 해결책인듯 싶다.
만일 부호없는 정수가 필요하다면 value >>> 0.

단점이 있다면 가독성 문제인 듯 싶다. 코드만 봐서는 뭘 하는지 알아먹기 힘드니...

jsperf의 연산자 속도 체크 결과 링크는 여기.

댓글 2개: