Question Profil mystère Javascript - variables de fermeture


Je testais les performances (avec la chronologie du chrome) sur les cas si variable définie dans une fermeture. Donc, ses valeurs ne seraient pas exposées à l'utilisateur.

Comme prévu run_proto_fn exécuter quelques fois plus vite et avec des collections de mémoire minimales, et du tas de mémoire faible.

Mais run_proto_obj est arrivé à faire exactement le contraire, comme si il était coûteux d'avoir des valeurs non-fonction aux propriétés de propriété de prototype d'objet.

Quelqu'un peut-il partager une certaine clarté ici?

SOME = function(){};
SOME.prototype.exe = function(v){
	var x = {
		a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
		b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
		c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
	};
	return x[v];
};

SOME2 = function(){};
SOME2.prototype.exe = function(v){
	return this.exes[v];
};
SOME2.prototype.exes = {
	a:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
	b:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
	c:'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea, quae repudiandae eveniet cumque consequatur vitae aut. Nisi perspiciatis magnam explicabo optio reprehenderit dignissimos at porro quam, neque dolorum, architecto odit?',
};
SOME_FN = function(){};
SOME_FN.prototype.exe = function(v){
	var x = {
		a: function(p){this.p1 = p;return this;},
        b:function(p){this.p2 = p*3;return this;},
        c:function(p){this.p3 = p*99;return this;},
    };
  return x[v].call(this,42);
};

SOME_FN2 = function(){};
SOME_FN2.prototype.exe = function(v){
    return this.exes[v].call(this,42);	
};
SOME_FN2.prototype.exes = {
    a: function(p){this.p1 = p;return this;},
    b:function(p){this.p2 = p*3;return this;},
    c:function(p){this.p3 = p*99;return this;},
};

var a1 = a2 = a_fn1 = a_fn2 = [];
	

var run_local_obj = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x1 = new SOME();
		x1.exe('a');
		a1.push(x1);
	}
};
var run_proto_obj = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x2 = new SOME2();
		x2.exe('a');
		a2.push(x2);
	}
};
var run_local_fn = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x1 = new SOME_FN();
		x1.exe('a');
		x1.exe('b');
		x1.exe('c');
		a_fn1.push(x1);
	}
};
var run_proto_fn = function(){
	for (var i = 1000000 - 1; i >= 0; i--) {
		x2 = new SOME_FN2();
		x2.exe('a');
		x2.exe('b');
		x2.exe('c');
		a_fn2.push(x2);
	}
};
<button onclick="run_local_obj(this)">local obj</button>
<button onclick="run_proto_obj(this)">proto obj</button>
<button onclick="run_local_fn(this)">local obj FN</button>
<button onclick="run_proto_fn(this)">proto obj</button>


J'ai entendu une phrase:

la variable de fermeture est définie à chaque exécution de la fonction

mais quand même, je brouille.


13
2018-02-02 23:53


origine


Réponses:


J'ai essayé de faire les mesures et tout d'abord, j'ai remarqué qu'il est difficile de comprendre ce qui se passe en utilisant simplement le code de votre question.

Si je lance ces tests un par un (en cliquant sur les boutons et en regardant la chronologie), les résultats diffèrent beaucoup pour chaque exécution suivante. De quelques pistes, il ressemblait au troisième (run_local_fn) est généralement plus longue que les autres.

Ensuite, j'ai essayé de les exécuter dans l'ordre inverse (boutons de 4 à 1) et j'ai obtenu un résultat complètement différent - le run_local_obj était le plus long.

J'ai donc modifié un peu le code de test pour pouvoir obtenir des résultats stables.

Code complet est là, vous pouvez cloner le repo et le tester localement.

Voici comment je lance chaque test dans Chrome (je l'ai lancé en utilisant python -m SimpleHTTPServer 8082 à l'intérieur de js-perf-test dossier):

  • Ouvrez l'onglet avec http: // localhost: 8082 / perf.html, ouvrir des outils de développement
  • Commencer l'enregistrement chronologique
  • Cliquez sur le bouton
  • Attendez les résultats dans la console (min / max / mean)
  • Arrête l'enregistrement de la chronologie

Les résultats sont stables et reproductibles (timings et timeline), voici un des tests:

Alors qu'est-ce que nous voyons ici est:

1) le run_proto_obj est le plus rapide et run_local_obj est proche de lui.

Je pense qu'il est prévu pour run_proto_obj être le plus efficace car il utilise un objet défini statiquement avec des chaînes. Et le moteur JS est probablement capable d’optimiser le run_local_obj, alors le x objet est réutilisé et non créé à chaque fois.

2) le run_local_fn est le plus lent.

Ici nous avons le local x calcul de chaînes d'objets et dynamiques, plus floating parties que dans d'autres tests.

3) Le run_proto_fn est plus rapide que run_local_fn, mais plus lent que les deux premières fonctions.

Je pense que cela est également prévu, l'objet avec a, b, c est défini une seule fois (il est donc plus rapide que run_local_fn).

Et en comparant les deux premières fonctions, il calcule les chaînes résultantes de manière dynamique, ce qui ralentit le processus.

Donc, revenons à votre question:

Comme prévu, run_proto_fn s'exécute plusieurs fois plus rapidement et avec des collectes de mémoire minimales, et une mémoire insuffisante.   Mais run_proto_obj s'est avéré exactement opposé, comme s'il était coûteux d'avoir des valeurs non fonctionnelles au niveau des propriétés de propriété du prototype d'objet.

Il me semble que vous n'avez pas configuré l'expérience correctement. Selon les résultats ci-dessus, run_proto_obj est en fait le plus rapide.

Mise à jour: Je viens d'essayer le même test dans Firefox, les résultats sont similaires:

  • `run_local_obj '- 344.85ms
  • `run_proto_obj '- 151.47ms
  • `run_local_fn '- 788.08ms
  • `run_proto_fn '- 265.21ms

le run_proto_obj est le plus rapide et run_local_fn est le plus lent.


12
2018-02-08 13:16