루프 내에서 null 유형의 값이 변경되는 이유는 무엇입니까?


109

Chrome 콘솔에서이 스 니펫을 실행합니다.

function foo() {
    return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());

1000 번 인쇄해야 false하지만 일부 컴퓨터 false에서는 여러 번 반복 한 다음 true나머지 를 인쇄 합니다 .

여기에 이미지 설명 입력

왜 이런 일이 발생합니까? 그냥 버그입니까?


4
그것은 ... 나를 위해 진실 1000 배를 반환
호앙 롱

2
나는 262 허위 / 738 진실이, 그것의 버그를 생각
잭스 텔러

1
크롬 콘솔에서는 이상하다 : 배열로 푸시하고 배열을 기록하면 모두 false. 있는 그대로의 수는 true크롬에서 변동합니다.
dandavis

1
@ HoàngLong 질문에서 말했듯이 일부 컴퓨터에서만 발생합니다. 또한 일부 버전의 Chrome에서만 발생할 수 있습니다
Agos

2
@ HoàngLong 확실히 당신은 크롬에서 실행하고 있는지 확인
노비타

답변:



37

실제로 V8 JavaScript 엔진 ( Wiki ) 버그입니다.

이 엔진은 Chromium, Maxthron, Android OS, Node.js 등에서 사용됩니다.

Reddit 주제 에서 찾을 수있는 비교적 간단한 버그 설명 :

최신 JavaScript 엔진은 JS 코드가 실행될 때 최적화 된 기계 코드로 컴파일됩니다 (Just In Time 컴파일). 그러나 최적화 단계에는 장기적인 속도 향상의 대가로 초기 성능 비용이 발생하므로 엔진은 방법이 얼마나 일반적으로 사용되는지에 따라 방법이 가치가 있는지 여부를 동적으로 결정합니다.

이 경우 최적화 된 경로에만 버그가있는 것처럼 보이지만 최적화되지 않은 경로는 제대로 작동합니다. 따라서 처음에는 메서드가 의도 한대로 작동하지만 어느 시점에서 충분히 자주 루프에서 호출되면 엔진이 최적화하기로 결정하고 버그가있는 버전으로 교체합니다.

이 버그는 V8 자체 ( commit ), Chromium ( bug report ) 및 NodeJS ( commit ) 에서 수정 된 것으로 보입니다 .


버그가 여전히 Node.js 6.2.2에 있다는 것을 확인했습니다.
Michael Shopsin

오늘 (21.06) V8 엔진에서 수정되었으며, 곧 관련 소프트웨어가 업데이트 될 것이라고 생각합니다.
Sergey Novikov

v8 수정을 Node.js 6.2.x 로 백 포팅 하는 것은 TheAlphaNerd 소유의 이슈 # 7348 로 이미 진행 중 입니다.
Michael Shopsin

18

변경 이유에 대한 직접적인 질문에 답하기 위해 버그는 Chrome에서 사용하는 V8 JS 엔진의 "JIT"최적화 루틴에 있습니다. 처음에는 코드가 작성된대로 정확하게 실행되지만 더 많이 실행할수록 최적화의 이점이 분석 비용을 능가 할 가능성이 더 커집니다.

이 경우 루프에서 반복 실행 된 후 JIT 컴파일러는 함수를 분석하여 최적화 된 버전으로 대체합니다. 불행히도 분석은 잘못된 가정을하고 최적화 된 버전은 실제로 올바른 결과를 생성하지 않습니다.

특히 Reddit 사용자 RainHappens는 유형 전파 오류 라고 제안 합니다 .

또한 일부 유형 전파를 수행합니다 (변수 등의 유형에서와 같이). 변수가 정의되지 않거나 null 인 경우 특수한 "감지 불가능"유형이 있습니다. 이 경우 옵티마이 저는 "null은 감지 할 수 없으므로 비교를 위해"정의되지 않은 "문자열로 바꿀 수 있습니다.

이것은 코드 최적화의 어려운 문제 중 하나입니다. 성능을 위해 재 배열 된 코드가 원본과 동일한 효과를 갖도록 보장하는 방법입니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.