Traitement asynchrone

Traitement asynchrone - Javascript/Node.js - Programmation

Marsh Posté le 01-06-2020 à 15:07:57    

Bonjour,

 

J'ai une fonction qui traite un fichier texte, cela peut parfois durer quelques secondes, je voudrais donc afficher une indication de chargement en cours mais je me suis complètement perdu dans les async, await, promises et .then. [:jimbotte]
Je n'ai vraiment plus les idées claires... :fou:

 

Voici ma fonction :

Code :
  1. function filemanager(filelist) {
  2. const file = filelist[0];
  3. const reader = new FileReader();
  4. reader.onload = function() {
  5.  document.getElementById('loading').style.display = 'block';
  6.  parse(this.result);
  7.  createTable();
  8.  document.getElementById('loading').style.display = 'none';
  9. };
  10. reader.readAsText(file);
  11. }
 

Je voudrai donc afficher mon élément "loading" le temps que le traitement de la fonction parse() et createTable() soit réalisé. Ces deux fonctions doivent être réalisées de manière séquentielle (l'une après l'autre) mais dans un contexte asynchrone afin de permettre l'affichage du loader.
Un coup de pouce ? [:agkklr]


Message édité par MaybeEijOrNot le 01-06-2020 à 15:08:54

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 01-06-2020 à 15:07:57   

Reply

Marsh Posté le 01-06-2020 à 16:18:15    

Exemple de ce que j'ai tenté :

 
Code :
  1. function filemanager(filelist) {
  2. const file = filelist[0];
  3. const reader = new FileReader();
  4. reader.onload = async function() {
  5.  console.log('start');
  6.  document.getElementById('loading').style.display = 'block';
  7.  console.log('step 1');
  8.  const res = this.result;
  9.  const func1start = new Promise(function(resolve, reject) {
  10.   parse(res);
  11.   console.log('step 2');
  12.   createTable();
  13.   resolve(true);
  14.  });
  15.  try {
  16.   const func1end = await func1start;
  17.  } finally {
  18.   document.getElementById('loading').style.display = 'none';
  19.   console.log('end');
  20.  }
  21. };
  22. reader.readAsText(file);
  23. }
 

Cela semble pas mal, mais l'affichage de l'élément "loading" ne se fait pas...

 

EDIT : donc dans ce cas là j'ai dans la console au fur et à mesure, "start" puis "step 1" puis "end" et aucun affichage du loader entre "start" et "step 1".


Message édité par MaybeEijOrNot le 01-06-2020 à 16:34:23

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 01-06-2020 à 16:39:38    

Ok je crois que le problème est lié au DOM et non vraiment à l'asynchronité. :fou:


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 01-06-2020 à 17:17:31    

Réglé comme ça :

 
Code :
  1. function filemanager(filelist) {
  2. const file = filelist[0];
  3. const reader = new FileReader();
  4. setTimeout(function() { document.getElementById('loading').style.display = 'block'; }, 0);
  5. reader.onload = async function() {
  6.  const res = this.result;
  7.  const func1start = new Promise(function(resolve, reject) {
  8.   parse(res);
  9.   createTable();
  10.   resolve(true);
  11.  });
  12.  try {
  13.   const func1end = await func1start;
  14.  } finally {
  15.   document.getElementById('loading').style.display = 'none';
  16.  }
  17. };
  18. reader.readAsText(file);
  19. }
 

Si quelqu'un a plus propre, qu'il n'hésite pas surtout. :o

 

EDIT : on oublie, en fonction des propriétés CSS attribuées ça bug, en fonction de si ça passe en cache ou non ça bug. Il semblerait que ce soit mission impossible...

 

EDIT2 : pour l'instant je suis passé sur une solution alternative, j'affiche mon indication dans un évènement qui précède très largement celui qui déclenche ma fonction filemanager.


Message édité par MaybeEijOrNot le 01-06-2020 à 18:20:49

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 01-06-2020 à 20:23:31    

Code :
  1. function filemanager(filelist) {
  2. const file = filelist[0]
  3. const reader = new FileReader()
  4. document.getElementById('loading').style.display = 'block'
  5. reader.onload = ()=>{
  6. const res = this.result;
  7.  parse(res);
  8.  createTable();  
  9.  document.getElementById('loading').style.display = 'none';
  10. }
  11. reader.readAsText(file);
  12. }


devrait suffire
https://developer.mozilla.org/fr/do [...] readAsText


---------------

Reply

Marsh Posté le 01-06-2020 à 21:07:23    

J'ai testé (quelques petites erreurs) :

Code :
  1. function filemanager(filelist) {
  2. const file = filelist[0]
  3. const reader = new FileReader()
  4. document.getElementById('loading').style.display = 'block';
  5. reader.onload = (e) => {
  6.  parse(e.target.result);
  7.  createTable();
  8.  document.getElementById('loading').style.display = 'none';
  9. };
  10. reader.readAsText(file);
  11. }
 

Mais non ça ne le fait pas, le problème vient du fait que le DOM ne se met pas à jour tant que l’exécution du JS n'est pas terminée. Je pensais qu'en passant le JS en asynchrone ça changerait mais non. L'une des astuces trouvée sur stackoverflow est d'utiliser la fonction setTimeout afin de sortir la partie du code qu'elle contient de la pile en cours d'exécution :
https://stackoverflow.com/questions [...] js-running
https://stackoverflow.com/questions [...] ctions-run

 

Mais ça ne fonctionne pas bien chez moi...


Message édité par MaybeEijOrNot le 01-06-2020 à 21:08:57

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 01-06-2020 à 21:22:10    

euh, non. LE dom se mettra à jour dès que possible
2eme point : le onload d'un reader est très rapide

 

est ce que parse et create table sont synchrones ou asynchrones ? Est ce qu'elles sont longues ?

Message cité 1 fois
Message édité par flo850 le 01-06-2020 à 21:28:50

---------------

Reply

Marsh Posté le 01-06-2020 à 22:33:55    

Perso, je serais passé par settimeout() pour le loading.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 01-06-2020 à 23:08:18    

flo850 a écrit :

euh, non. LE dom se mettra à jour dès que possible
2eme point : le onload d'un reader est très rapide

 

est ce que parse et create table sont synchrones ou asynchrones ? Est ce qu'elles sont longues ?


Je ne fais que constater... Le DOM se met à jour certes dès que possible, faut juste définir le quand c'est possible. :o
Je n'ai pas eu le temps de lire x articles mais ça semble compliqué et peu documenté du peu que j'ai pu lire.

 

Le problème n'est pas lié au onload mais bien au parsing et surtout au createTable (les deux sont synchrones). D'ailleurs le traitement demande tellement de ressources que même un gif ne s'anime plus, la page est bloquée. Donc j'ai deux pistes, soit tenter d'attacher deux évènements distincts voir si ça peut permettre de dissocier soit tenter d'utiliser un web worker.


Message édité par MaybeEijOrNot le 01-06-2020 à 23:10:16

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 08:05:35    

Donc settimzoit sur le loading, mais surtout essaye d'optimiser ton traitement ainsi que la génération du dom

 

Est ce que tu peux déporter le traitement ôté serveur pour n'avoir que la lecture des données ?
Est ce que tu construit les nœuds a la mains où tu utilise des templates ?


---------------

Reply

Marsh Posté le 02-06-2020 à 08:05:35   

Reply

Marsh Posté le 02-06-2020 à 08:30:17    

C'est vrai qu'un traitement JS qui consomme tellement de ressources que même un gif ne s'anime plus, c'est bizarre :/ Soit le client a un CPU de calculette, soit il faut effectivement revoir la façon dont est effectué le traitement.
Pourquoi ne pas découper le traitement en petits paquets et chaque traitement est fait séquentiellement et entre 2 traitements, tu laisses le CPU respirer qq ms ?
Dans un programme en Delphi, j'avais une grosse boucle de traitement et ça bloquait aussi le CPU à 100%. En ajoutant un processDispatch() à chaque tour de boucle, le CPU pouvait traiter d'autres choses sur le PC.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-06-2020 à 08:40:37    

Faut que je teste aussi ta solution Rufo mais oui l'une des contraintes c'est de se passer de serveur à ce moment là. Avec un serveur tout serait cent fois plus simple...
Je génère à la main sur mon fichier test environ 500 lignes de tableau. Cela prend chez moi un peu moins d'une seconde. J'estime que le temps d'attente est acceptable dans la mesure où l'utilisateur va déjà passer plusieurs secondes à aller chercher son fichier.
Je pourrai en effet ne générer qu'une partie du tableau dans le DOM et faire un chargement sur le scroll mais pas certain que ce soit vraiment mieux que de bloquer la page au grand max 3 secondes pour ensuite être tranquille.


Message édité par MaybeEijOrNot le 02-06-2020 à 08:41:52

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 08:56:20    

mets au moins une pagination sur le tableau : tu parse les données une seule fois, mais tu n'affiche que 100 éléments avec page suivantes/pages précédentes

 

Mais 500 lignes de tableau à générer, normalement c'est assez indolore, à moins qu'il n'y a 500 colonnes et/ou que tu fasse un traitement lourd). Je pense que c'est là que tu dois  améliorer les choses.

 

Message cité 1 fois
Message édité par flo850 le 02-06-2020 à 08:59:08

---------------

Reply

Marsh Posté le 02-06-2020 à 09:23:00    

typiquement, avec des templates : https://www.html5rocks.com/en/tutor [...] /template/
si tu as besoin de la compatibilité IE , il faut ajouter un script (attention, IE avec ses perfs de merde va probablement s'etouffer très très vite)

 

Est ce que tu peux tester un truc simple comme ça ?

Code :
  1. // json est de la forme { data : [{col1:value, col2,value, ...} ... ]
  2.  
  3.  
  4. function filemanager(filelist) {
  5. const file = filelist[0]
  6. const reader = new FileReader()
  7. document.getElementById('loading').style.display = 'block';
  8. document.getElementById(myLovelyTableContent).innerHTML = ''
  9. reader.onload = (e) => {
  10.  
  11. try{
  12.    const json = JSON.parse(e.target.result)
  13.    let tableContent = json.data.map(dataLine=>{
  14.       return `<tr><td>${dataLine.col1}</td><td>${dataLine.col2}</td><td>${dataLine.col3}</td></th>`
  15.      })  //je prends chaque ligne de données et j'en construit une ligne de tableau
  16.      .join(''); //map retourne un tableau et je veux une chaine de caractère
  17.    document.getElementById(myLovelyTableContent).innerHTML = tableContent
  18.    document.getElementById('loading').style.display = 'none';
  19.  }catch(e){
  20.     // json pété
  21.  }
  22. };
  23. reader.readAsText(file);
  24. }
 
Code :
  1. <table id="myLovelyTable">
  2.   <thead>
  3.      <th> COl1</th>
  4.      <th> COl2</th>
  5.      <th> COl3</th>
  6.      <th> COl4</th>
  7.  </thead>
  8.  <tbody  id="myLovelyTableContent">
  9.  
  10.  </tbody>
  11. </table>
 

Message cité 1 fois
Message édité par flo850 le 02-06-2020 à 09:23:14

---------------

Reply

Marsh Posté le 02-06-2020 à 10:48:23    

flo850 a écrit :

mets au moins une pagination sur le tableau : tu parse les données une seule fois, mais tu n'affiche que 100 éléments avec page suivantes/pages précédentes


Oui c'est ça que je sous-entendais par un chargement sur le scroll.

 
flo850 a écrit :

typiquement, avec des templates : https://www.html5rocks.com/en/tutor [...] /template/
si tu as besoin de la compatibilité IE , il faut ajouter un script (attention, IE avec ses perfs de merde va probablement s'etouffer très très vite)

 

Est ce que tu peux tester un truc simple comme ça ?

Code :
  1. // json est de la forme { data : [{col1:value, col2,value, ...} ... ]
  2.  
  3.  
  4. function filemanager(filelist) {
  5. const file = filelist[0]
  6. const reader = new FileReader()
  7. document.getElementById('loading').style.display = 'block';
  8. document.getElementById(myLovelyTableContent).innerHTML = ''
  9. reader.onload = (e) => {
  10.  
  11. try{
  12.    const json = JSON.parse(e.target.result)
  13.    let tableContent = json.data.map(dataLine=>{
  14.       return `<tr><td>${dataLine.col1}</td><td>${dataLine.col2}</td><td>${dataLine.col3}</td></th>`
  15.      })  //je prends chaque ligne de données et j'en construit une ligne de tableau
  16.      .join(''); //map retourne un tableau et je veux une chaine de caractère
  17.    document.getElementById(myLovelyTableContent).innerHTML = tableContent
  18.    document.getElementById('loading').style.display = 'none';
  19.  }catch(e){
  20.     // json pété
  21.  }
  22. };
  23. reader.readAsText(file);
  24. }
 
Code :
  1. <table id="myLovelyTable">
  2.   <thead>
  3.      <th> COl1</th>
  4.      <th> COl2</th>
  5.      <th> COl3</th>
  6.      <th> COl4</th>
  7.  </thead>
  8.  <tbody  id="myLovelyTableContent">
  9.  
  10.  </tbody>
  11. </table>
 



J'utilise à l'heure actuelle des createElement que je greffe entre eux puis que j'ajoute uniquement à la fin à mon DOM, j'ai l'impression que ça agit comme les fragments HTML car j'avais testé les fragments sans noter d'amélioration. Mais oui je pourrai regarder les templates. Par contre il y a un truc qui me fait peur dans ton code c'est le map, je sais qu'au début j'étais sur un foreach, j'ai voulu passer sur un map à un moment pour simplifier mon code et au final je suis retourné sur un foreach car ça m'avait complètement tué mes performances (10s au lieu d'1s). Je pense que les maps n'aiment pas faire des traitements lourds et le problème c'est que je récupère un csv et je dois traiter les données avant de les afficher, elles ne sont pas prêtes à l'emploi. Je dois garder en mémoire le csv parsé mais non traité en mémoire pour actualiser l'affichage en fonction des entrées client.

 


EDIT : je teste dès que je peux, c'est à dire dans la semaine...


Message édité par MaybeEijOrNot le 02-06-2020 à 10:49:15

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 12:28:30    

Je sais pas ce que tu fais dans ton createTable() mais il me semble que faire un .innertHTML = provoque la réévaluation du DOM.
Donc mieux vaut tout faire dans une variable puis faire une seule affectation une fois pour toute dans innerHTML que faire pleins de concaténations.


Message édité par rufo le 02-06-2020 à 12:28:44

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-06-2020 à 13:25:19    

map/foreach ont exactement la même performance, c'est autre chose qui t'a mangé tes perfs. Tu as combien de colonnes ?

 

ne garde pas en mémoire le CSV, mais garde en mémoire la version exploitable (un json par exemple)

 

et oui, une seule modif du dom améliore énormement les perfs


Message édité par flo850 le 02-06-2020 à 13:25:34

---------------

Reply

Marsh Posté le 02-06-2020 à 14:39:05    

J'utilise appendChild pour ajouter mon noeud à la fin.
 
Pour le map/foreach, de souvenir je n'avais changé que ça pour retrouver des perfs "correctes", suffit que l'un cause en effet une réévaluation du DOM et pas l'autre pour des raisons que je ne connais pas. C'est bien au-delà de mes connaissances, probablement des choses qu'en temps normal on ne peut remarquer et qui ressortent dans des cas critiques comme le mien.
J'ai 6 colonnes avec parfois plusieurs données dans une cellule et je garde en mémoire un tableau d'objets JS mais avec les données quasi brutes.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 16:32:52    

Je suis sûr a 100% que ce genre de tableau ne devrait pas faire ramer  
 
Cet après midi, j'ai travaillé sur du parsing de fichier excel côté client, 300 lignes, 8 colonnes, et le navigateur ne fait pas la gueule . A mon avis, tu ne cherche pas au bon endroit en te focalisant sur le DOM.


---------------

Reply

Marsh Posté le 02-06-2020 à 16:45:17    

Pour l'instant je ne cherche rien, je me disais que c'était possible un freeze d'une seconde sur ce genre de traitement (on est d'accord que je génère dynamiquement le tableau ?).
Cela me semblait aussi acceptable compte-tenu du temps de freeze rapporté au temps que l'utilisateur va déjà mettre pour aller chercher son fichier donc je me disais que simplement mettre un avertissement de chargement en cours suffisait.
Maintenant si vous me dites que je peux générer dynamiquement mon tableau en quelques ms (< 250 ms on va dire) je vais en effet chercher de ce côté.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 19:08:46    

1- Je viens de comprendre que je n'ai pas compris ta solution Rufo sur le setTimeout, j'ai déjà testé de mettre l'affichage du message de chargement en cours dans un setTimeout, ça améliore un peu mais en fonction des propriétés CSS ça peut annuler l'effet...
 
2- J'ai fait un template, mon code est plus clair mais je ne gagne pas en perfs.
 
3- En effet j'ai quelques innerHTML qui trainent, en les passante en commentaire ça accélère bien, donc je vais travailler à les remplacer. Pour le reste, on va déjà voir ce que ça donne le travail sur les innerHTML.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 19:41:46    

Avoir éliminé les innerHTML semble accélérer tout ça, mais ça m'a surtout permis de trouver une fonction qui ralentie tout ça :

Code :
  1. function parseDate(date, reverse) { //true: from digit date to timestamp; false: from timestamp to digit date
  2. if(reverse === true) {
  3.  date = new Date(date)
  4.  return (+Date.parse(date.toLocaleDateString()) / 1000 - +date.getTimezoneOffset() * 60);
  5. } else {
  6.  date = new Date(+date * 1000);
  7.  return date.toLocaleDateString('fr-FR', { year: 'numeric', month: '2-digit', day: '2-digit' });
  8. }
  9. }


Une idée ? (je passe dans le sens "false" )
Parce qu'en écrivant le message j'en vois une :

Spoiler :

Il manque un point-virgule à la troisième ligne. En le rajoutant ça accélère, mais pourquoi je n'ai pas eu d'erreur levée ??? :fou:

 

Je n'ai pas l'air con avec ça. :lol:

 


Par contre j'ai des données avec parfois quelques balises HTML (genre des <br> ), comment ce passer du innerHTML ? Je remplace les balises à la volée ? Car j'ai testé, ça ralentit quand même de laisser juste un innerHTML (ou du moins celui-là).


Message édité par MaybeEijOrNot le 02-06-2020 à 19:45:13

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 20:23:33    

Ben non, dans innerHTML, tu peux mettre du HTML, ça pose pas de pb. Donc tes <br />, tu peux les laisser sauf si pour le rendu final, t'en veux pas.
 
Edit : en js, le ; à la fin d'une ligne n'est pas obligatoire.

Message cité 1 fois
Message édité par rufo le 02-06-2020 à 20:24:07

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-06-2020 à 20:24:40    

mais au passage "des" inner html  
 
tu ne veux pas tout mettre dans une grosse chaine de caractère et faire 1 innerhtml au bout ?


---------------

Reply

Marsh Posté le 02-06-2020 à 20:26:42    

C'est clair, ça serait plus rapide.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-06-2020 à 21:36:31    

rufo a écrit :

Ben non, dans innerHTML, tu peux mettre du HTML, ça pose pas de pb. Donc tes <br />, tu peux les laisser sauf si pour le rendu final, t'en veux pas.
 
Edit : en js, le ; à la fin d'une ligne n'est pas obligatoire.


 
Le but c'est de virer le innerHTML, donc oui je sais qu'on peut mettre du HTML dedans c'était bien pour ça que je l'avais utilisé. Maintenant comment faire sans, cela me semble compliqué, soit j'élimine le HTML pour ne laisser que du texte sans même pouvoir faire un retour à la ligne si je comprends bien, soit faut que je parse moi-même pour créer les noeuds et les ajouter (semble compliqué).
 
Pour le point-virgule, je viens de lire rapidement un truc, je préfère ne pas approfondir puisque a priori son omission fait débat sur les perfs. :o  
 
Le coup de la chaîne, je n'aime pas trop. Par contre j'ai trouvé des boucles à factoriser. :bounce:


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 22:11:48    

C'est ma fonction parseDate qui semble critique à l'heure actuelle, elle me bouffe 400 ms, elle est appelée deux fois pour chaque ligne de données. Une idée ?


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 02-06-2020 à 22:39:00    

T'as quoi comme données en entrée et tu veux les transformer en quoi au final ?
 
Parce qu'il y a peut-être moyen de prendre "des raccourcis" ?


Message édité par rufo le 02-06-2020 à 22:39:35

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-06-2020 à 23:15:59    

MaybeEijOrNot a écrit :


 
Le but c'est de virer le innerHTML, donc oui je sais qu'on peut mettre du HTML dedans c'était bien pour ça que je l'avais utilisé. Maintenant comment faire sans, cela me semble compliqué, soit j'élimine le HTML pour ne laisser que du texte sans même pouvoir faire un retour à la ligne si je comprends bien, soit faut que je parse moi-même pour créer les noeuds et les ajouter (semble compliqué).
 
Pour le point-virgule, je viens de lire rapidement un truc, je préfère ne pas approfondir puisque a priori son omission fait débat sur les perfs. :o  
 
Le coup de la chaîne, je n'aime pas trop. Par contre j'ai trouvé des boucles à factoriser. :bounce:


:cry:
tu fais de la micro optimisation alors que là, c'est majeur
 
pour le parsing de date, c'est forcement un peu long :/
 
8,050 ops/s ±1.87%

Code :
  1. let d = new Date()
  2. let s = d.toLocaleDateString('fr-FR', { year: 'numeric', month: '2-digit', day: '2-digit' })


 
216,629 ops/s ±2.49%

Code :
  1. let d = new Date()
  2. let m = d.getMonth()
  3. m = m < 10 ? '0'+m : m
  4. let y = d.getFullYear()
  5. let j = d.getDate
  6. j = j < 10 ? '0'+j : j
  7. let s = d+'/'+m+'/'+j


 
243,894 ops/s ±1.08%

Code :
  1. let d = new Date()
  2. let m = d.getMonth()
  3. m = m < 10 ? '0'+m : m
  4. let y = d.getFullYear()
  5. let j = d.getDate
  6. j = j < 10 ? '0'+j : j
  7. let s = `${d}/${m}/{j}`


 
https://jsbench.me/


---------------

Reply

Marsh Posté le 02-06-2020 à 23:19:26    

Je pense même qu'en se passant des objets, ça irait encore plus vite.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-06-2020 à 23:27:33    

pas sur qu'on gagne tant que ca, et faut gérer a la main la conversion


---------------

Reply

Marsh Posté le 03-06-2020 à 10:12:42    

flo850 a écrit :


:cry:
tu fais de la micro optimisation alors que là, c'est majeur
 
pour le parsing de date, c'est forcement un peu long :/
 
8,050 ops/s ±1.87%

Code :
  1. let d = new Date()
  2. let s = d.toLocaleDateString('fr-FR', { year: 'numeric', month: '2-digit', day: '2-digit' })


 
216,629 ops/s ±2.49%

Code :
  1. let d = new Date()
  2. let m = d.getMonth()
  3. m = m < 10 ? '0'+m : m
  4. let y = d.getFullYear()
  5. let j = d.getDate
  6. j = j < 10 ? '0'+j : j
  7. let s = d+'/'+m+'/'+j


 
243,894 ops/s ±1.08%

Code :
  1. let d = new Date()
  2. let m = d.getMonth()
  3. m = m < 10 ? '0'+m : m
  4. let y = d.getFullYear()
  5. let j = d.getDate
  6. j = j < 10 ? '0'+j : j
  7. let s = `${d}/${m}/{j}`


 
https://jsbench.me/


 
Je savais bien que tenter de bien faire les choses était une mauvaise idée, j'aurai vraiment dû y aller à la bourrin et parser moi-même comme je l'ai fait partout ailleurs. :o  
 
Je testerai quand même de tout mettre dans une string et d'ajouter à la fin mais je ne suis pas persuadé de l'efficacité. Disons que ça va m'éliminer des réinterprétations du DOM si je ne les ai pas toutes enlevées, sinon ça devrait faire la même chose. Mais c'est quand même moins beau et surtout plus galère à gérer.
Faut savoir qu'après avoir créé mon tableau, je repasse en revue chaque cellule de la dernière colonne afin de récupérer ses dimensions pour gérer son overflow car je veux limiter mes hauteurs de lignes (sans "perdre" de données donc j'ajoute la possibilité d'agrandir la hauteur de la ligne au besoin). Mais ça n'a pas l'air de vraiment consommer de ressources.
 
Sinon j'ai tout rebasculé dans une même boucle quelque chose comment 6 boucles, et en effet ça ne gagne pas grand chose car si je comprends ça crée des problèmes de gestion de la mémoire qui sont aussi longs que de recommencer les boucles. :pt1cable:


Message édité par MaybeEijOrNot le 03-06-2020 à 10:15:03

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 03-06-2020 à 18:54:45    

flo850 a écrit :


243,894 ops/s ±1.08%

Code :
  1. let d = new Date()
  2. let m = d.getMonth()
  3. m = m < 10 ? '0'+m : m
  4. let y = d.getFullYear()
  5. let j = d.getDate
  6. j = j < 10 ? '0'+j : j
  7. let s = `${d}/${m}/{j}`


 
https://jsbench.me/


Très efficace, merci ! (euh enfin ça va vite mais le formatage ce n'est pas encore ça, je vais ajuster)
Quand j'aurai un peu plus de temps, je vais essayer la technique de la string et je vais tenter d'utiliser ton site de benching pour repérer d'autres aberrations car pour l'instant j'utilise l'outil de performances de FF et ce n'est pas évident d'avoir les réponses directes sans faire de différentiel.
 
EDIT : version corrigée du code :

Code :
  1. let d = new Date(+date * 1000); //date is a timestamp in seconds instead of milliseconds
  2. let m = d.getMonth() + 1;
  3. m = m < 10 ? '0'+m : m;
  4. let y = d.getFullYear();
  5. let j = d.getDate();
  6. j = j < 10 ? '0'+j : j;
  7. let s = `${j}/${m}/${y}`;

Message cité 1 fois
Message édité par MaybeEijOrNot le 03-06-2020 à 19:00:40

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 04-06-2020 à 14:20:57    

MaybeEijOrNot a écrit :


Très efficace, merci ! (euh enfin ça va vite mais le formatage ce n'est pas encore ça, je vais ajuster)
Quand j'aurai un peu plus de temps, je vais essayer la technique de la string et je vais tenter d'utiliser ton site de benching pour repérer d'autres aberrations car pour l'instant j'utilise l'outil de performances de FF et ce n'est pas évident d'avoir les réponses directes sans faire de différentiel.
 
EDIT : version corrigée du code :

Code :
  1. let d = new Date(+date * 1000); //date is a timestamp in seconds instead of milliseconds
  2. let m = d.getMonth() + 1;
  3. m = m < 10 ? '0'+m : m;
  4. let y = d.getFullYear();
  5. let j = d.getDate();
  6. j = j < 10 ? '0'+j : j;
  7. let s = `${j}/${m}/${y}`;



 
Ca que j'adore avec ES6 c'est la décomposition et les literals
 

Code :
  1. const d2 = new Date(+date * 1000);
  2. let [d,m,y] = [d2.getDate(), d2.getMonth() + 1, d2.getFullYear()];
  3. let s = `${d < 10 ? '0'+d : d}/${m < 10 ? '0'+m : m}/${y}`;


Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed