10
votes

Implications de performance d'utilisation de style fonctionnel JavaScript vs "procédure"

a joué par quelqu'un de benchmarking, ou peut être un lien vers un article sur ce sujet? Particulièrement intéressé par les résultats IE, car généralement la performance JS n'est pas un problème dans d'autres navigateurs.

J'aimerais savoir à quel point il est plus lent de faire quelque chose comme: P>

var numbers = [1, 2, 3, 4, 5, 6, 7];
var results = [];

for (var i = 0; i < numbers.length; i++) {
  var number = numbers[i];
  var result;
  // do some stuff
  results.push(result);
}


5 commentaires

Peut-être un point de théâtre, mais c'est-à-dire que <9 n'applique même pas []. Carte . Vous corrigez array.pototype vous êtes-vous?


Joe Armstrong, de la renommée d'Erlang, donne toujours aux conseils lorsque des questions comme ceci que les programmeurs devraient écrire les plus beaux programmes qu'ils puissent. Code comme vous voulez que vos idées se reflètent - à l'aide d'algorithmes de base bien et appropriés, bien sûr! - et laissez les gars qui soupçonnent la V8, le Tracemonkey et Jscript traitent de faire des appels de fonction plus rapidement. Ne vous emboîtez pas avec du code que, dans un an, ne fera pas de choses plus rapides de toute façon.


@Crescent Yeah Patching Array.Prototype ou Utilisez quelque chose comme ceci: documentCloud.github.com/underscore


@Pointy j'aime beau code, mais après avoir travaillé sur un projet où mon travail à temps plein était à peu près "corrigé ce code de sorte que ce ne soit pas insupportablement lent dans IE", maintenant que je commence à partir de ce qui va être un important webapp ( Pensez gmail), je ne veux pas faire des erreurs.


@Inifinité, il est imprudent de parler en généralistes mais je suis d'accord avec pointeau et le point qu'il fait. Beaucoup de fois si quelque chose est insupportablement lent, ce n'est pas les bibliothèques qui sont la question - c'est des choses comme le code qui lisait une valeur constante sur chaque passage à travers une boucle et une boucle et des choses muettes de ce type. Bien sûr, je fais une énorme généralisation. :-) Au fait - cela pourrait vous aider dans votre travail: Whitefrost.com/documents/html/technical/dhtml/jsprof.html


4 Réponses :


2
votes

Celui-ci est vraiment intéressant:

http://www.slideshare.net/madrobby/extreme-javascript-performance

Toutefois, dans les moteurs JS Ready Ecmascript5 avec Native Array.Map () , les choses peuvent changer considérablement.


1 commentaires

Eh bien .. ressemble à la diapositive 18 répondons à peu près à cette question :(



3
votes

ne contient pas de contenu avec le manque de preuve sur ce sujet, j'ai écrit une courte référence. C'est loin d'être parfait mais je pense que cela répond à la question.

Je l'ai couru dans IE 8 / victoire, et pendant que la méthode fonctionnelle est plus lente, elle ne sera jamais le goulot d'étranglement en code réel. (Sauf si vous faites des choses que vous ne devriez pas faire dans le client de toute façon)

Je vais donc utiliser l'approche de nettoyage chaque fois que je dois choisir (yay)

( Meilleur de 5)
Méthode fonctionnelle: 453ms
Ancienne approche scolaire: 156ms xxx


1 commentaires

Chaque fois que j'entends parler de la microoptimisation: YouTube.com/watch?v=65- Rbbwzqdu et fonctionnalité = youtu.be



1
votes

C'est très intéressant aussi:

http://documentcloud.github.com/underscore/test/test.html

Les résultats varient d'un navigateur au navigateur, car le soulignement essaie d'utiliser l'alternative native où disponible.


0 commentaires

3
votes

TL; DR: Plus votre syntaxe, plus rapide. Évitez la programmation fonctionnelle lorsque vous optimisez la vitesse.

J'ai décidé de proposer une référence qui inclurait les choses communes que vous pourriez faire avec la programmation fonctionnelle, qui vient de produire des agrégations. Le repère résultant peut être exécuté ici. Les résultats suivants sont de fin 2020, mais au moment où vous lisez ceci, peut-être certaines optimisations ou quelque chose qui a été fait, vous pouvez le réutiliser avec ce lien, mais si ce lien est mort, le code est également collé ci-dessous. . J'ai utilisé les résultats de Chrome, mais alors que certains navigateurs courent des choses plus rapidement que d'autres, ils maintiennent tous la même commande de performance. S'avère que Firefox est bien plus lente à partir de cette écriture, comme Chrome est 5 fois plus rapide que Firefox. Bord est aussi rapide que chrome. Safari est également aussi rapide que le chrome. Le nœud est également aussi rapide que le chrome. Depuis chrome, safari et nœud fonctionnent tous sur le moteur V8, je soupçonne qu'ils seraient toujours la même vitesse: p>

https://jsbench.me/dvkgymlimu/1 p>

La première fonction "Aggregate_fonctionnel", utilise toutes les nouvelles syntaxes, les opérateurs de diffusion, réduire, etc. De loin le plus lent, courir à environ 10 m ops / sec. Étant donné que c'est le plus lent, mais dirige toujours un fou de 10 millions de fois chaque seconde, je pense que cela prouve que l'argument est discutable pour tous les cas les plus extrêmes. Si 10 millions de fois par seconde ne sont pas assez rapides pour vous, suivez-la. P>

La fonction suivante utilise la boucle "de" et est quatre fois plus rapide que la version fonctionnelle. Je ne m'attendais pas vraiment à ce niveau de performance Boost. P>

La dernière fonction 'Aggregate_imperative_idx', utilise des choses JavaScript "anciennes", aucun opérateur de propagation, pas de boucle "de", juste une boucle indexée. Sinon, pour les mots-clés "let" et "const", il devrait fonctionner sur Netscape Navigator. J'étais heureux de constater que l'utilisation de "var" n'a pas amélioré les performances. Cela m'aurait rendu triste. Il a fini par être 8.2x plus rapide que la mise en oeuvre fonctionnelle, à 82 M OPS / SEC. P>


function aggregate_functional (numbers) {
  if (numbers.length == 0) {
    throw new Error("aggregate() requires at least one number")
  }
  const sum = numbers.reduce((s, n) => s += n)
  let min = Math.min(...numbers)
  let max = Math.max(...numbers)
  const average = sum / numbers.length
  return {
    sum,
    average,
    min,
    max,
  }
}

function aggregate_imperative (numbers) {
  if (numbers.length == 0) {
    throw new Error("aggregate() requires at least one number")
  }
  let sum = 0
  let min = numbers[0]
  let max = numbers[0]
  for (const val of numbers) {
    if (val < min) min = val
    if (val > max) max = val
    sum += val
  }
  const average = sum / numbers.length
  return {
    sum,
    average,
    min,
    max,
  }
}

function aggregate_imperative_idx (numbers) {
  if (numbers.length == 0) {
    throw new Error("aggregate() requires at least one number")
  }
  let sum = 0
  let min = numbers[0]
  let max = numbers[0]
  for (let i = 0; i < numbers.length; i++) {
    const val = numbers[i]
    if (val < min) min = val
    if (val > max) max = val
    sum += val
  }
  const average = sum / numbers.length
  return {
    sum,
    average,
    min,
    max,
  }
}


0 commentaires