3

La questionPourquoi ce nouveau code est-il plus lent que mon ancien code?

J'ai remplacé un code que j'avais des problèmes de performance avec certains nouveau code que je ne m'y attendais à mieux performer. Au lieu de cela, il a fait pire. Je voudrais comprendre pourquoi c'est le cas pour que je puisse travailler avec le moteur d'exécution V8 de Chrome plutôt que contre.

L'arrière-plan

Mon code est un jeu par navigateur. Pendant le fonctionnement normal, beaucoup de coordonnées xy circulent entre les fonctions. Un exemple de ceci avant que je « fixe » les choses avait l'air quelque chose comme ceci:

function doSomething1(x,y) { 
    /* Do work here */ 
    return {x: newx, y: newy}; 
} 

function doSomething2(x,y) { 
    /* Do work here */ 
    return {x: newx, y: newy}; 
} 

function doSomething3(x, y) { 
    var result1 = doSomething1(x, y); 
    var result2 = doSomething2(result1.x, result1.y); 

    /* Do work here */ 
    return {x: newx, y: newy}; 
} 

Vous avez l'idée .. beaucoup de fonctions qui s'appellent, de retour des petits objets anonymes avec des propriétés et des valeurs xy plumer hors d'eux.

Lorsque mon jeu s'exécute, il présente des problèmes de récupération de place. Le graphique de la mémoire est très épineux et le taux de trame n'est pas lisse. Pour atténuer ce risque, j'ai décidé de ré-écrire mon code afin qu'il a suivi ce modèle:

function doSomething(x,y,out) { 
    /* Do work here */ 
    out[0] = newx; 
    out[1] = newx; 
} 

var xy = [0,0]; /* Some 2-length array for results */ 
doSomething(5,6,xy); 
/* 'Return' value in xy */ 

De cette façon, il n'y a qu'une « allocation » et les valeurs sont remplacées dans le tableau qu'il appelle des fonctions sur la chaîne.

Cela a en effet eu pour effet de lisser le graphique d'allocation de mémoire. Il a également eu l'effet secondaire inattendu de réduire mon taux de cadre de 50%!

Pourquoi cela devrait-il être? Quelles sont les optimisations en jeu que je peux contourner? Comment puis-je mieux écrire ce code pour travailler avec le runtime V8?

Mise à jour

enquête plus poussée a montré que le code n'a pas été en fait 50% plus lent. Ce n'était que plus lent lorsque le nouveau code était hébergé sur 127.0.0.1 et l'ancien code sur Internet. C'est étrange, mais ce n'est pas la même question. Je vais fermer cette question.

+0

Une raison possible est que vous utilisez le tableau 'out' avec une taille dynamique. Pourriez-vous essayer de créer un tableau avec une taille fixe et laissez-nous savoir les résultats :) Aussi vous n'avez pas mentionné combien d'éléments avez-vous, pourriez-vous ajouter cette information? – Warlock

+0

"L'optimisation prématurée est la racine de tous les maux" - Donald Knuth – Warlock

Répondre

0

Lorsque vous écrivez

out[0] = newx 

V8 ne connaîtra d'allouer un nouvel objet avec le champ « 0 » et de s'y tenir newx en elle. Lorsque vous continuez avec

out[1] = newy 

Il doit retrouver l'objet qu'il vient d'allouer et allouer plus d'espace pour le champ « 1 ». C'est beaucoup plus cher que {x: newx, y:newy} parce que dans le dernier cas V8 sait déjà combien de champs il y aura. Je ne sais pas grand-chose sur l'optimisation de javascript ou de votre jeu, donc c'est difficile pour moi de faire d'autres recommandations. J'espère que vous avez déjà examiné les problèmes d'algorithmes et que vous essayez maintenant de faire quelques ajustements - les algorithmes sont là où de grandes améliorations peuvent être apportées.

Questions connexes