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 :

webworker transfer data


Sujet :

JavaScript

  1. #1
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 464
    Points : 4 646
    Points
    4 646
    Par défaut webworker transfer data
    Bonjour,

    j'en appel aux gouroux du JS...

    j'essaye de deleguer (via un webWorker) un calcul D3 (https://d3js.org/ pour ceux qui ne connaissent pas). le calcul en soit se passe bien, le probleme est qu'il me genere un tableau d'objects. ces objets sont des MultiPolygon qui contiennent les coordonnes de millions de points (qui permettent de colorer des zones) voici a quoi ca ressemble :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    [
    {
      coordinates: [
        [x,y],
        [x,],// etc ... des milliers de fois
      ],
      type: "MultiPolygon",
      value: 0
    },
    {
      coordinates: [
        [x,y],
        [x,],// etc ... des millions de fois
      ],
      type: "MultiPolygon",
      value: 10
    },
    etc...
    ]
    => le renvoyer au main thread prend ~500ms ce qui me genere des warnings d'execution time, et plus genant : ca fait ramer la page

    de plus, ayant plusieurs workers en parallele, j'ai l'impression que des que le 1er worker commence a "renvoyer sa donnee au main thread", celui-ci est "bloque le temps de la copie de l'object", ce qui retarde encore plus les suivants

    voici mon code :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function generateCoor(params) {
        const {datas} = params;
        const contours = d3.contours().size([256, 256]);
        const cntrs = contours.thresholds(20)(datas.data);
        console.log(cntrs);
        postMessage({action:'generateCoor', datas:cntrs});
        // postMessage({action:'generateCoor', datas:cntrs}, [cntrs.buffer]); // idealement, ce que j'essaye de faire
    }
    je n'arrive pas a le passer dans le param de transfer developer.mozilla.org/en-US/docs/Glossary/Transferable_objects car il faudrait le convertir "object transferable"
    et je ne sais pas comment faire ca :/

    merci d'avance a ceux qui ont le temps de se pencher sur mon probleme
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Bonjour,
    as-tu essayé de passer par un Uint8Array ?

    Si contours.thresholds(20)(datas.data) te renvoie un array tu peux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const u8 = new Uint8Array(cntrs);
    et tu auras accès à u8.buffer.

  3. #3
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 464
    Points : 4 646
    Points
    4 646
    Par défaut
    contours.thresholds(20)(datas.data) ne me retourne pas un simple tableau, mais un tableau d'objects...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const u8 = new Uint8Array(cntrs);
    console.log('u8', u8);
    => u8 Uint8Array(20)*[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, buffer: ArrayBuffer(20), byteLength: 20, byteOffset: 0, length: 20]


    j'ai l'impression que ça m'a écrasé tout le contenu (mais c’à me retourne bien un tableau de 20 entrées.... vides )
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    j'ai l'impression que ça m'a écrasé tout le contenu
    c'est le comportement normal, les données n'étant pas des données binaires l'espace est alloué mais les valeurs sont mises à zéro.
    23.2.5.1 TypedArray ( ...args ).

    Ceci étant tu ne va pas trop avoir le choix que d'« encoder » tes données si tu veux utiliser les TypedArray.

    Néanmoins il ne faudrait pas que l'« encodage/décodage » des données ne soient trop gourmand par rapport au gain obtenu lors de la transaction postMessage.

    J'ai fait quelques essais avec la création 1M (1024 * 1024) objets légers et il ressort que le plus rapide reste le passage direct du jsonObjet. Certes la transaction est longue mais aucun codage/décodage à effectuer.

    Une autre méthode a été d'utiliser TextEncoder() qui permet après un encode du JSON.stringify(jsonObjet) d'avoir une vitesse de « transfert » 40(*) fois plus rapide que le « transfert » direct mais qui est gourmande au « décodage » et qui au final, en cumulant, est plus lent que le « transfert » direct.

    J'ai fait également avec une méthode custom de « codage/décodage » et l'on du même ordre qu'avec TextEncoder() en moins bien.

    Donc pas de réelle gain à envisager sauf à éventuellement changer ton approche ou structure des données.
    Tout ceci est sous réserve qu'il n'existe pas une solution dite « miracle », le passage par des blob ou autres ne me paraissant pas forcément meilleurs !



    (*) c'est un ordre de grandeur et non une valeur absolue

  5. #5
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 464
    Points : 4 646
    Points
    4 646
    Par défaut
    merci pour ton retour tres instructif

    j'avais effectivement teste un encodage / decodage, mais j'avais tres vite abandonne cette idee, car j'avais constate des lenteurs de fou...

    je pense que je vais suivre ton conseil et revoir ma copie...

    merci
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Dans ton cas il peut exister également la solution d'itérer et de ne pas traiter la totalité dans le « même bloc », cela peut au final devenir transparent à l'utilisation.

    Tu pourrais traité chaque polygone comme un objet du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    objet = {
      "type": "MultiPolygon",
      "value": 0,
      "coordinates": new Uint8Array()
    }
    ainsi tu pourras utiliser coordiantes.buffer pour la transaction, mais bon cela restera un choix de structure de départ.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WM15] transferer DATA (MOBILE)
    Par beginner1 dans le forum Windev Mobile
    Réponses: 1
    Dernier message: 22/01/2013, 16h50
  2. Data Transfer Workbench et IDocs
    Par ludovic.fernandez dans le forum SAP
    Réponses: 0
    Dernier message: 04/02/2008, 17h56
  3. Data Transfer Object
    Par ngomsi dans le forum C#
    Réponses: 1
    Dernier message: 29/01/2008, 10h44
  4. Réponses: 4
    Dernier message: 07/03/2007, 09h19

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