IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

array: for() vs map()


Sujet :

JavaScript

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 155
    Points : 75
    Points
    75
    Par défaut array: for() vs map()
    Bonjour

    Depuis peu j'utilise array.map() à la place des boucles for() malgré un avis assez répandu selon lequel cette méthode serait plus lente et donc pas adaptée au 'hot code'.
    Or cet article récent par exemple taille un short à la boucle for...

    Alors voilà, question simple et directe : selon vous peut-on oublier définitivement les for() si par exemple on ne cible que les navigateurs récents ?

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 155
    Points : 75
    Points
    75
    Par défaut
    Je connaissais pas le while power, effectivement c'est futé, et le + rapide !


    Sinon for() est x2 + rapide (avec FF) que map().

    Mais il y a 2 autres arguments dans l'article : le scope indépendant (qui évite de s'emmeler les 'i' et autres variables) et l'aspect mémoire :
    It also points out something that you would not notice if merely viewing a for() vs .forEach() test like this. for() uses more memory than .forEach()!

    Alors question très générale : en quoi est ce que l'utilisation de la mémoire est importante face à la vitesse ??
    Est ce que ce choix là peut vraiment influer sur la performance globale, sachant qu'il peut s'intégrer dans du 'hot code' justement et dans des processus qui bouffent déjà pas mal de mémoire... (du three.js en l'occurrence) ?

  4. #4
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 19
    Points : 24
    Points
    24
    Par défaut
    Question épineuse aux multiples réponses.
    C'est pas une question d'utilisation face à la vitesse, les 2 sont intimement lié.
    Faut rester raisonnable, un pc a 8Go de ram, bon tu a de la marge , maintenant un vieux tel a 512Mo , c'est la criticité de départ qui influence tes choix (qu'est se que je veut, sous quelle platforme ...).
    Exemple tu a besoin d'un tableau de 200Mo, plutot que de l'envoyer à une fonction (qui va crée une copie, tu te retrouve avec 400Mo ), exteriorise ta variable pour que les 2 fonctions y ai accès.
    D'ailleurs, a tu réelement besoin de ses 200Mo ? , dès le départ ?

    "Est ce que ce choix là peut vraiment influer sur la performance globale"
    Oui et non, si tu a une empreinte mémoire de 1Mo sur un pc actuel, tu comprend bien que non, maintenant 250Mo sur une tel de 512Mo, bon la ya un énorme problème

    Vitesse et mémoire sont deux choses bien distinct mais qui fonctionne ensemble, l'un impact l'autre et vice versa.
    Je pense que c'est surtout une question d'algorithmie, chose que la majorité des devs oublie aujourd'hui malheureusement.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 155
    Points : 75
    Points
    75
    Par défaut
    Ok merci !

    Tout d'abord une précision de départ : il ne s'agit pas d'itérer 3 <li> dans un <ul> mais par exemple d'itérer une géométrie complète dans une boucle de requestAnimationFrame() ... Donc le genre de truc où la performance compte vraiment.


    si tu a une empreinte mémoire de 1Mo sur un pc actuel, tu comprend bien que non, maintenant 250Mo sur une tel de 512Mo, bon la ya un énorme problème
    > Mais est ce qu'on peut dire que l'utilisation de la mémoire n'influe sur la vitesse que si elle vient à manquer, et que sinon ça ne pose pas trop de problème ?

    Exemple tu a besoin d'un tableau de 200Mo, plutot que de l'envoyer à une fonction (qui va crée une copie, tu te retrouve avec 400Mo ), exteriorise ta variable pour que les 2 fonctions y ai accès.
    D'ailleurs, a tu réelement besoin de ses 200Mo ? , dès le départ ?
    > Ça c'est justement un truc que je suis pas sur d'avoir bien saisi dans le fonctionnement général du js : le fait qu'une fonction "crée une copie"... Alors mettons que oui, j'ai besoin de traiter 200Mo dans ce genre de contexte...

    A ce moment là si je fais le code suivant je "déplie" 2 fois les 200Mo dans la mémoire c'est ce que ça veut dire ? C'est la raison pour laquelle il faut éviter les récursives ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var pomper = function( tableau_de_200Mo ){
    	var repomper = function( tableau_de_200Mo ){
    		var truc = ....
    		return truc;
    	}
    	return repomper( tableau_de_200Mo );
    }
    xx = pomper( tableau_de_200Mo );
    Et que veut dire "extérioriser" la variable dans ce cas ?

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 19
    Points : 24
    Points
    24
    Par défaut
    "Mais est ce qu'on peut dire que l'utilisation de la mémoire n'influe sur la vitesse que si elle vient à manquer, et que sinon ça ne pose pas trop de problème ?"

    C'est bien plus complexe que sa, dans l'absolue, quand tu crée un tableau de 200Mo, c'est pour t'en servir, tu va surement bouclé dessus, faire des recherche dessus,
    et la le proc y tourne.
    Une appli, au dela du programme a elle aussi besoin de mémoire, si tu a une appli qui consome 500Mo et qui tu a 512Mo de ram(on fait abstraction de l'os et autre appli),
    tu comprend qu'il ne te reste que 12Mo de mémoire utile.


    "Ça c'est justement un truc que je suis pas sur d'avoir bien saisi dans le fonctionnement général du js : le fait qu'une fonction "crée une copie" "
    Se n'est pas lié au js mais c'est un problème générale.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var tableau_de_200Mo = [...];
    var pomper=function(tableau_de_200Mo){
      // ici en gros l'argument tableau_de_200Mo est une copie (en vrai c'est beaucoup plus complexe que sa)
    }
    pomper(tableau_de_200Mo);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var tableau_de_200Mo = [...];
    var pomper=function(){
      // ici tu travail sur le tableau puisqu'il est global, il ni a pas de coipe
    }
    pomper();
    En passant un argument, il crée une copie de l'argument

    En php, peut etre a déja tu vu sa

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function pomper(&variable)
    ici on passe notre variable en réference, c'est a dire qu'on lui fournit l'adresse du tableau, il ne crée donc pas de copie puisque il sait ou est le tableau originale

    C'est un sujet complexe, sa dépend d'énormément de choses, ne serait ce du navigateur (moteur)

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 155
    Points : 75
    Points
    75
    Par défaut
    Ok, donc il faut minimiser les (gros) arguments de fonction et privilégier les globales dans un scope ...

    Ce qui m'étonne un peu c'est qu'un tableau ou un objet en argument de fonction reste en référence non ?


    Je laisse ouvert pour le cas où des passants ont des remarques là dessus ...

  8. #8
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Citation Envoyé par thejocker9 Voir le message
    Exemple tu a besoin d'un tableau de 200Mo, plutot que de l'envoyer à une fonction (qui va crée une copie, tu te retrouve avec 400Mo ), exteriorise ta variable pour que les 2 fonctions y ai accès.
    Citation Envoyé par thejocker9 Voir le message
    "Ça c'est justement un truc que je suis pas sur d'avoir bien saisi dans le fonctionnement général du js : le fait qu'une fonction "crée une copie" "
    Se n'est pas lié au js mais c'est un problème générale.
    Salut,

    Cela m'étonne il me semble que les objets comme les tableaux sont transmis par référence et non par valeur, il n’y aurait donc pas de copie de faite par la fonction lors de la transmission des arguments...

    C'est à confirmer pour JS mais je pense que pour JS c'est comme pour Java... Le contraire m'étonnerait, ce serait vraiment pas terrible je trouve...

    A approfondir...

    EDIT : J'ai testé ceci :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function func(tab){
      console.log(tab); // affiche ["un", "deux", "trois"]  
      tab[1] = "2";  
    }
     
    var unTableau = ["un","deux", "trois"];
     
    func(unTableau);
    console.log(unTableau); // affiche ["un", "2", "trois"]
    On voit bien que l’instruction tab[1] = "2"; affecte le tableau "unTableau" ce qui prouve que le tableau "tab" n'est pas une copie du tableau "unTableau" mais la variable tab pointe sur le tableau "unTableau"...

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    un petit exercice toujours intéressant à faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var tab = [ 1, 2, 3, 4, 5];
    var tab_2;
    function modifTab(t) {
        t[2] = 'deux';
        return t;
    }
    console.log('tab 1: ', tab);
    console.log(tab_2 = modifTab(tab));
    console.log('tab 2: ', tab);
    tab_2[3] = 'trois';
    console.log('tab 3: ', tab);

  10. #10
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Merci, je vais regarder...

    Juste avant j'ai aussi édité mon message pour y posté un exemple...

  11. #11
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut


    #Array.map est une des fonctions de base dans l'écriture de JS dans un style fonctionnel.

    J'en suis très friand, surtout avec ES6. Par exemple, si on a une liste d'utilisateurs et qu'on veut obtenir la liste des noms de tous les majeurs par ordre du plus jeune au plus vieux, on peut écrire ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    users
    .filter(user => user.age >= 18)
    .sort((alice, bob) => alice.age - bob.age)
    .map(user => user.name)
    .map(name => name.toUppercase())
    Chaque opération est appliquée l'une après l'autre, sans besoin de déclarer de nouvelles variables ou scopes. Je trouve ça très élégant et très pratique à l'usage. La question des performances est secondaire selon moi, ce sont des micro optimisations insignifiantes.
    One Web to rule them all

  12. #12
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 19
    Points : 24
    Points
    24
    Par défaut
    Après diverses éssais, il semblerai que les objets simples comme String, Boolean, Number (les types natif) soit passés par valeur, par contre les tableau, c'est passé par réference.

    C'est à confirmer pour JS mais je pense que pour JS c'est comme pour Java... Le contraire m'étonnerait, ce serait vraiment pas terrible je trouve...
    Tu avait donc raison Beginner.; ah trop de c pas assez de java .

    Désolé donc pour cette fausse information , décidement le js est a part, au moins j'aurait apprit quelque chose meme si je ne l'éxploiterais pas

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 155
    Points : 75
    Points
    75
    Par défaut
    Chaque opération est appliquée l'une après l'autre, sans besoin de déclarer de nouvelles variables ou scopes. Je trouve ça très élégant et très pratique à l'usage. La question des performances est secondaire selon moi, ce sont des micro optimisations insignifiantes.
    C'est clair que pour la lisibilité et la maintenance c'est ce qu'il y a de mieux.

    Mais il y a des cas où la performance compte ... Et dans ton exemple :
    - le tableau est itéré 4 fois
    - d'après le fiddle de SpaceFrog array.map() est jusqu'à 20 fois plus lente dans Chrome ...

    Dans la majorité des cas je suis d'accord que ça ne gène pas, mais dans l'exemple que je donnais (gros tableau itéré par un code exécuté à haute fréquence) ça gène bp plus...

Discussions similaires

  1. JAG - Java API for Google Maps web Services
    Par gueekAddict dans le forum Projets
    Réponses: 1
    Dernier message: 16/12/2012, 15h59
  2. Google crée Analytics for Google Maps
    Par Hinault Romaric dans le forum APIs Google
    Réponses: 2
    Dernier message: 22/04/2012, 16h18
  3. array for noob
    Par xian21 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 27/09/2007, 11h50
  4. array for noob (je parle de moi ^^)
    Par xian21 dans le forum C#
    Réponses: 15
    Dernier message: 26/09/2007, 14h06
  5. MAPPING configuration error for request URI
    Par Turtle dans le forum JBuilder
    Réponses: 1
    Dernier message: 17/02/2005, 11h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo