0

Ensuite, je suppose, la question plus complète est, "Comment ces considérations sont-elles affectées lorsque le moteur Javascript est connu (sur une base de moteur populaire)." La raison pour laquelle je pense que je dois demander à "communauté" est que ceux qui créent des choses comme Node.js, comme Strongloop, écrivent aussi du code comme util.inherits, une fonction dans laquelle, au lieu de: TheConstructorFunction.prototype.constructor = TheConstructorFunction ils créent une définition de propriété qui a lui-même 4 propriétés étant définies:Considérant le code pour un moteur Javascript inconnu, quelles considérations ont le plus d'impact sur la vitesse d'exécution et la conservation de la mémoire?

ctor.prototype = Object.create(superCtor.prototype, { 
    constructor: { 
     value: ctor, 
     enumerable: false, 
     writable: true, 
     configurable: true 
    } 
}); 

cela me semble inefficace, mais, je ne l'ai toujours cherché à en écrire un meilleur Javascript pour 3 ans par opposition aux auteurs de code comme celui-ci. Y a-t-il une explication de pourquoi ceci est ou n'est pas efficace? Une réponse indique que util.inherits n'est pas inefficace car les opérations de sous-classe sont rares. Mais compte tenu du fait que certaines bibliothèques traitent des centaines et des milliers d'opérations de sous-classes entre la construction et l'observation des résultats de test, si Node.js utilise en interne util.inherits, cela affecte le temps de développement de ses consommateurs. Je pense que, sur ce plan, l'efficacité est importante et j'espère que util.heritas n'est pas utilisé en interne. Je ne comprends même pas le but de util.inherits. Pourquoi l'avoir du tout? Je pense que cela favorise une inefficacité aggravante. require('util').inherits(C1,C2); est presque aussi lent et probablement moins de C1.prototype=Object.create(C2.prototype); C1.prototype.constructor=C1; Si c'est juste destiné à attirer les consommateurs, je suis cool avec ça. Mon souci est de savoir si ces pros utilisent cette fonction en interne, car les bibliothèques plus grandes dépendront de l'efficacité de Node.js. Quant à faire .constructor non-énumérable ... Je pense que le cas où son "énumérabilité" importe est rare et devrait être laissé au consommateur, mais si les opérations internes dépendent des util.heritas, ce n'est pas vraiment laissé de côté au consommateur.

+0

L'exemple que vous avez donné de 'ctor.prototype' n'est pas le même que le' prototype.constructor' que vous avez comparé. C'est des pommes aux oranges. – TylerY86

+0

"* certaines bibliothèques traitent des centaines et des milliers d'opérations de sous-classes qui se déroulent entre la construction pour tester l'observation des résultats *" - oh vraiment? Qu'est ce qui te fait penser ça? Et non, même cette échelle importe peu, comparée par exemple. à lire les fichiers sources à partir du disque. "* presque aussi et probablement plus lent *" - ni, en fait. Si vous êtes si curieux, comparez-les vous-même. Et non, les fonctions standard de la bibliothèque ne favorisent pas l'inefficacité, elles favorisent la * simplicité *, ce qui fait gagner aux développeurs beaucoup plus de temps que ne le pourraient les micro-optimisations. – Bergi

+0

@ Bergi, vous pourriez avoir raison, et j'accepte votre défi. Je les comparerai à un moment donné dans un proche avenir.Parce que, si vous avez raison, je perds juste plus de temps à y penser. Mais si vous avez tort, alors vous et toute une série de blogueurs/éducateurs/professionnels répandez un concept assez flagrant. J'ai écrit un logiciel de gestion de parc éolien en PHP et il utilise près de 20-50 classes différentes en fonction du type de requête, j'envisage d'implémenter le système dans Node.js mais je prévois d'avoir un système sous-jacent similaire à Wordpress. .. donc il y a un exemple. – flcoder

Répondre

0

Les auteurs des moteurs JavaScript répondent le mieux à cette question.

C'est un processus appelé optimisation des performances.

Here's Google's guide. Here's Mozilla's guide. Rendre Node.js exécuter javascript fast est au cœur de l'activité de Strongloop. Ils prennent l'optimisation javascript seriously. Il y a quelques pièges comme this.

La plupart du temps cependant, ne pas bloquer la boucle d'événements - promesses d'utilisation, les opérations async, callbacks, etc.

votre code de référence avec des cas de test réalistes raisonnables. Assurez-vous de vérifier la couverture. Une fois que vous êtes à la cause principale de votre recherche d'optimisation des performances, vous devez commencer à creuser plus profondément. Vous devez profiler votre code. Thorsten Lorenz a un vieillissement mais encore la plupart du temps pertinent GitHub repository qui contient beaucoup d'informations utiles V8 d'initié. Il y a beaucoup de développeurs qui publient blog articles, like this guy. Vous devez vous assurer qu'ils savent de quoi ils parlent. Il fait.

Bluebird, une implémentation notoirement performante de Promises, est le summum de l'optimisation correcte.Ils ont an article et a guide sur des choses qu'ils ont notées qui sont simplement des choses communes qui tuent l'optimisation.

Mise à jour

L'exemple que vous avez donné de la mise en œuvre de util.s une chaîne d'héritage devrait probablement être une question distincte. Je ne suis pas sûr qu'ils soient patchés là-bas, je devrais voir le reste de la classe et les prototypes.

Voir this MDN article pour les avantages et les inconvénients et les variations des moyens connus pour mettre en œuvre l'héritage, en particulier pour l'utilisation de Object.create, mais les autres aussi bien.

La seule bonne raison de l'extension d'un prototype intégré (alias « patching singe ») est de rétroporter les caractéristiques des moteurs JavaScript plus récents; par exemple, Array.forEach, etc.

Here's un raisonnement expliquant pourquoi ce genre de chose est fait. I answered a question il n'y a pas très longtemps sur l'injection d'une classe dans le haut d'une chaîne d'héritage dans le but d'ajouter une méthode d'extension à tous leurs enfants. Ce n'est pas une bonne idée.

Il s'avère que Object.create dans l'implémentation util.js de inherits peut avoir été une tentative d'optimisation à l'origine. Selon early revisions, il a rendu le prototype implicitement immuable, améliorant théoriquement la performance de la résolution des méthodes. Pedantically parlant, il n'a jamais été correct, et a toujours été essentiellement un hack autour des capacités d'héritage prototypiques de JavaScript. Les nouvelles révisions remplacent cela par Object.setPrototypeOf.

Edit: Si vous votiez contre, j'apprécierais pourquoi.

+0

Ceci est un bon exemple de la réponse que je recherche. – flcoder

+0

Je vais m'en inspirer si je trouve des détails généraux plus significatifs. Le réglage des performances peut aller vraiment en profondeur. [Consultez cette question] (http://stackoverflow.com/questions/39576177/locate-corresponding-js-source-of-code-which-is-not-optimized-by-v8/39762720#39762720). – TylerY86

+0

J'ai édité ma question et ai porté 'prototype.constructor' à' TheConstructorFunction.prototype.constructor' ... qui est la même chose que leur définition de propriété de constructeur 'ctor.prototype'. Je comprends qu'ils font cela pour le rendre non-énumérable, mais je ne comprends pas pourquoi. Si, je fais une classe de type Collection, ok ... peut-être alors je vais aller de l'avant et rendre certaines propriétés non énumérables. Mais pour tout autre type de classe, je ne suis pas sûr que ça vaut la peine de "cacher" la propriété du constructeur. Je vois juste ce genre de ballonnement partout qui me fait me demander si même les pros savent ce qu'ils font. – flcoder

1

Cela me semble inefficace

n ° efficacité n'a pas d'importance ici. Le sous-classement est une opération rare, et même si le code est plus lent que la simple affectation (il n'y a probablement pas beaucoup de différence), cela n'affecte pas les performances. Ce qui compte, en particulier pour les fonctions de bibliothèque comme utils.inherit qui sont utilisées partout, est correction. Alors, pourquoi utilisent-ils les attributs de propriété? Pour rendre le .constructor non énumérable, comme c'est la norme pour .prototype objets qui sont créés nativement et donc généralement attendus. Etant donné que ni la vitesse ni la mémoire ne doivent être prises en compte ici, les optimisations telles que vous les attendez ne se produisent pas ici.

+0

J'ai mis à jour ma réponse parce qu'il n'y a pas assez de place pour répondre à votre conclusion ici. Mais pensez à ce que vous dites ... que je suis en train de lire: "Ni la vitesse ni la mémoire NE DOIVENT ÊTRE PRISES EN CONSIDÉRATION pour les fonctions de la bibliothèque comme utils.inherits qui sont UTILISÉS PARTOUT" Ce qui compte le plus, c'est la "correction". Je pense que l'exactitude est importante, bien sûr. Eh bien, c'est mieux, car si ce n'est pas le cas, c'est cassé.Mais ceci est mon problème. Je vois beaucoup (trop) de justification pour permettre le code sous-optimal. – flcoder

+0

@flcoder code correct est un code optimal :-) Mon argument concerne spécifiquement 'util.inherits', d'autres fonctions qui sont réellement critiques pour la performance (par exemple l'implémentation' Stream' de Node) * sont * optimisées dans les moindres détails, mais sans sacrifier la rectitude même alors. – Bergi

+0

Je comprends ce que vous dites ... parce que je l'ai entendu partout ... et je suppose que c'est ce que les professeurs enseignent; que c'est correct de gonfler quand vous avez l'impression qu'un certain morceau de code n'a pas besoin d'être concerné par l'optimisation. Premièrement, je pense que util.inherits est complètement inutile, et deuxièmement, je suis d'accord, dans vos mots, qu'il est "utilisé partout" et c'est ce que je trouve déconcertant. C'est ainsi que "les pros" roulent ...: P Et c'est pourquoi j'ai posé ma question à toute une communauté. Je veux voir quelles sources d'autres considèrent un conseil d'optimisation Javascript fiable. – flcoder