Partage
  • Partager sur Facebook
  • Partager sur Twitter

Script qui tourne pendant 30 secondes au lieu de 30 ms...

Sujet résolu
    10 août 2010 à 9:18:49

    Salut salut,

    Alors voilà, je suis en train de développer un petit jeu, et dès le début, j'ai un sacré problème :
    Mon script qui sert juste a afficher la base du jeu met très longtemps à tourner (30 secondes sur mon PC de merde, 3 à 10 secondes chez les autres ( qques temps ici ) ...
    C'est sensé donner une image dans ce genre là (mais avec juste des background color, pas encore des images, et juste les sols/murs) :
    Image utilisateur
    Mais le temps que met la boucle pour chaque carré augmente au fur et a mesure, pour atteindre plus d'une seconde par occurrence à la fin, chez moi...
    Voici le lien, si vous voulez tester (ATTENTION : ça prendra longtemps, ça fera surement croire à votre navigateur qu'il a planter, et ça risque de le faire sur les ordinateurs très légers) :
    http://tomp.hd.free.fr:1989/CRAWL/test.php

    Voici le code en question (vu qu'ya que ça dans le fichier pour le moment....) :

    var SCREEN_WIDTH = 21;
    var SCREEN_HEIGHT = 21;
    
    var POSITION_X = 15;
    var POSITION_Y = 15;
    
    var VISION_SIGHT = 8;
    
    var GRID = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
    	[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
    	[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
    	[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
    	[0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
    	[0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0],
    	[0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0],
    	[0,1,0,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
    	[0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
    	[0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0],
    	[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0],
    	[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
    	[0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,1,1,1,1,1,1,1,0,1,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0],
    	[0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0],
    	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
    
    
    function makeGrid() {
    	var game_screen = document.getElementById("game_screen");
    	var error_log = document.getElementById("error_log");
    /////////////////////////////////////timing :
    var time = new Date().getTime();
    error_log.innerHTML += "<b>original time</b> = " + time + "ms.<br />";
    /////////////////////////////////////////////
    	game_screen.style.width = 32*SCREEN_WIDTH + "px";
    	game_screen.style.height = 32*SCREEN_HEIGHT + "px";
    	for (var i = 0; i < SCREEN_HEIGHT; i++) {
    		var height = POSITION_Y - Math.floor(SCREEN_HEIGHT/2) + i;
    		for (var j = 0; j < SCREEN_WIDTH; j++) {
    			var width = POSITION_X - Math.floor(SCREEN_WIDTH/2) + j
    			// tile creation and positionning :
    			var tile = document.createElement("tile");
    			game_screen.appendChild(tile);
    			tile.style.position = "absolute";
    			tile.style.left = j*32 + "px";
    			tile.style.top = i*32 + "px";
    			tile.id = "tile" + height + "_" + width;
    			// coloring :
    			var distance = Math.round(Math.sqrt(Math.pow(height - POSITION_Y,2) + Math.pow(width - POSITION_X,2)));
    			//// error logging :
    			error_log.innerHTML += "width = " + width + " and height = " + height + ".<br />";
    			error_log.innerHTML += "distance = " + distance + ".<br />";
    			////////////////////
    			if ( distance > VISION_SIGHT ) {
    				tile.className ="not_seen";
    			} else if ( GRID[height][width] == 0 ) {
    				tile.className ="seen_wall";
    			} else {
    				tile.className ="seen_floor";
    			}
    		}
    	}
    /////////////////////////////////////timing :
    var new_time = new Date().getTime();
    error_log.innerHTML += "<b>script time</b> = " + (new_time - time) + "ms.<br />";
    /////////////////////////////////////////////
    }
    


    Merci d'avance, et @+!
    • Partager sur Facebook
    • Partager sur Twitter
      10 août 2010 à 13:43:13

      T'attends quoi de nous, en fait?
      Qu'on te donnes des pistes pour améliorer la performance? si c'est le cas commence par supprimer (ou écrire de manière différentes) tes logs lignes 65 et 66 car ils ont une consommation très importantes.
      Ensuite on peut regarder au cas par cas pour améliorer la perf (comme une meilleure utilisation des boucles)
      • Partager sur Facebook
      • Partager sur Twitter
        10 août 2010 à 14:02:14

        Va faire un petit tour sur le tuto des Bonnes pratiques javascript, particulièrement la partie sur innerHTML.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          10 août 2010 à 14:09:50

          comme le dit restimal, tu vires tes error_log.innerHTML et ça tourne dans les 100‑150 ms

          puis faudrait nettoyer un peu ton code, il est pas franchement mauvais mais les var dans tous les coins c'est pas lisible.

          Ah oui, <tile> c'est pas un élement html valide.
          • Partager sur Facebook
          • Partager sur Twitter
            10 août 2010 à 15:13:47

            Citation : restimel

            T'attends quoi de nous, en fait?
            Qu'on te donnes des pistes pour améliorer la performance?


            Ben ... ouais !

            Qu'un script "simple" comme ça (il fait 2 carrés et va chercher une donnée dans un tableau par occurrence) prenne autant de temps que ça, je ne trouve clairement pas ça normal, et vu que je suis pas génial en JS, je me doute qu'il y a des errerus de débutant ...
            Je vais déjà virer les innerHTML (qui ne sont là que pour les tests), mais j'aimerai aussi savoir s'il existe des méthodes meilleures (en terme de perf) pour la création des Tiles (que je vais surement garder comme ça, non valide, au moins pour un temps)...


            Citation : nod_

            puis faudrait nettoyer un peu ton code, il est pas franchement mauvais mais les var dans tous les coins c'est pas lisible.


            Tu proposerai quoi ?
            juste tout déclarer au début ?



            Ah, aussi, sur le lien des Bonnes pratiques javascript, il est écrit que

            Citation : Bonnes Pratiques

            Appeler innerHTML une seule et unique fois par élément. Si on l'utilise dans une boucle et que l'on rajoute un bout de chaîne à la fois, les performances sont aussi mauvaises — voir pire ! — qu'en utilisant le DOM.


            Hum ... DOM donne de mauvaises perfs aussi ?
            Ya qqchose d'autre, de plus efficace ?


            EDIT: au fait, MERCI !
            j'ai viré les deux innerHTML et : script time = 63ms.
            Ok, c'ets bon, résolu (mais si vous avez encore qqchose à dire sur mon script, vous privez pas, ça aide toujours !
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              10 août 2010 à 15:22:46

              ouaip. pas de surprises dans le reste du code comme ça.

              si t'as plus d'une centaine de cases ça pourrais être mieux de crée tes cases avec un .innerHTML de bourrin si t'en as moins reste avec le DOM propre.

              La façon dont tu calcul le temps de génération n'est pas bonne, tu mesure le temps d'execution du JS, or le DOM n'est pas complètement mise à jour quand tu affiches le résultat. Fait pas trop attention à ton temps de génération quoi.


              Dait attention à ne pas optimiser trop tot, ça sert à rien, évite seulement les erreur du type .innerHTML dans un boucle et tout ira bien.

              ( edit ) ton edit : non, y'a rien de plus efficace que innerHTML quand t'as plusieurs centaines ou milliers d'éléments à rajouter. t'as rien de plus efficace que le DOM pour toutes les autres manipulations. T'as pas le choix quoi :D
              • Partager sur Facebook
              • Partager sur Twitter

              Script qui tourne pendant 30 secondes au lieu de 30 ms...

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown