109 votes

Pourquoi la valeur de typeof null change à l’intérieur d’une boucle ?

L'exécution de ce fragment de code dans la console Chromée:

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

doit imprimer 1000 fois false, mais sur certaines machines d'impression false pour un nombre d'itérations, true pour le reste.

enter image description here

Pourquoi est-ce arrivé? Est-ce juste un bug?

74voto

Slumber86 Points 653

Il y a un bug chrome ouvert pour cela :

Question 604033 - compilateur JIT ne conservant ne pas de comportement de la méthode

Alors oui, c’est juste un bug !

37voto

Sergey Novikov Points 2990

C'est en fait un V8 moteur JavaScript (Wiki) bug.

Ce moteur est utilisé dans Chrome, Maxthron, Android OS, Node.js etc.

Relativement simple bug description vous pouvez trouver dans cette Reddit sujet:

Moderne JavaScript moteurs de compiler du code JS dans optimisé le code machine lorsqu'il est exécuté (Juste Au Moment de la compilation) pour le faire fonctionner plus rapidement. Cependant, l'optimisation de l'étape a quelques performances initiales de coûts dans de change à long terme de l'accélération, de sorte que le moteur dynamiquement décide si une méthode en vaut la peine en fonction de la façon dont souvent il est utilisé.

Dans ce cas, il semble y avoir un bug dans le chemin d'accès optimisé, alors que le unoptimized chemin fonctionne très bien. Au premier abord, cette méthode fonctionne comme prévu, mais si elle est appelée dans une boucle assez souvent à un certain point l' moteur de décider de l'optimiser et de le remplacer avec le buggy version.

Ce bug semble avoir été corrigé dans la V8 lui-même (s'engager), ainsi que dans Chrome (rapport de bug) et NodeJS (commit).

18voto

IMSoP Points 16089

Pour répondre à la question de pourquoi elle change, le bug est dans le "JIT" optimisation de la routine de la V8 JS moteur utilisé par Chrome. Au premier abord, le code est exécuté exactement comme c'est écrit, mais le plus vous courez, plus le potentiel existe pour les avantages de l'optimisation de l'emporter sur les coûts d'analyse.

Dans ce cas, après l'exécution répétée dans la boucle, le compilateur JIT analyses de la fonction, et la remplace par une version optimisée. Malheureusement, l'analyse fait une hypothèse erronée, et la version optimisée n'est pas réellement obtenir le résultat correct.

Plus précisément, Reddit utilisateur RainHappens suggère que c'est une erreur dans la propagation de type:

Il a également fait un peu de type de propagation (comme dans quels types une variable, etc peut être). Il y a un spécial "indétectable" type pour quand une variable n'est pas définie ou null. Dans ce cas, l'optimiseur de passe "null est indétectable, de sorte qu'il peut être remplacé par le "undefined" chaîne de caractères pour la comparaison.

C'est l'un des problèmes difficiles avec l'optimisation de code: comment garantir que le code qui a été réorganisés pour des performances toujours le même effet que l'original.

1voto

user835611 Points 41

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X