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

WinDev Discussion :

Quelle portée pour une variable locale [Généralités]


Sujet :

WinDev

  1. #1
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut Quelle portée pour une variable locale
    Bonjour,

    Je suis en train de faire un projet de migration de notre "ERP" maison vers un système imposé par notre groupe. Dans ce cadre, je suis amené à faire beaucoup de requêtes et de parcours sur celles-ci. La question existentielle que je me pose est résumable en un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DateMax est date
    POUR TOUT FichierAparcourir
      DateMax = "20010101"
      // Execution requete de recherche basée sur le fichier concerné - Je n'ai pas mis les tests de résultat d'exécution pour simplifier
      hExecuteRequeteSQL(sdReq,....)
      POUR TOUT sdReq
        SI sdReq.Date > DateMax alors
          DateMax = sdReq
        FIN
      FIN
     
      // Code de gestion du DateMax
      ...
    FIN
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    POUR TOUT FichierAparcourir
      DateMax est date
      DateMax = "20010101"
      // Execution requete de recherche basée sur le fichier concerné - Je n'ai pas mis les tests de résultat d'exécution pour simplifier
      hExecuteRequeteSQL(sdReq,....)
      POUR TOUT sdReq
        SI sdReq.Date > DateMax alors
          DateMax = sdReq
        FIN
      FIN
     
      // Code de gestion du DateMax
      ...
    FIN
    Les 2 bouts de code vont donner le même résultat.
    L'idée est de savoir si :
    - L'un des 2 va être plus rapide (FichierAparcourir a 200 000) enregistrements (et donc générer 200 000 requêtes à exécuter + parcourir) ?
    - La philosophie "du code propre" conseille le 2ème, dans le sens qu'une fois le parcours du fichier terminé, on n'en a donc plus besoin, et il ne sert à rien de laisser une variable devenue inutile en mémoire ?
    - On s'en cogne ?
    - Le gras, c'est la vie ?

    Faîtes couiner vos mulots et braire vos claviers ! Un peu de philo par les temps qui courent, ça change du quotidien !
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    A mon avis, la différence ici sera plus que négligeable, le plus gros du temps sera pris par la requête.
    Mais je vote pour la seconde version: si tu "déportes" le code dans une procédure, la variable sera locale à la procédure et ne servira que dans cette procédure.

    D'ailleurs en lisant le code je me dis que la seconde boucle ne sert à rien, si tu cherches "la date max", autant mettre ce critères dans la requête pour qu'elle ne renvoie qu'une seul ligne: la plus grande date trouvée supérieure à dateMax.
    Là je pense que la différence sera flagrante.

    Tatayo.

  3. #3
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Merci pour ta réponse tatayo,

    Fusionner les 2 traitements, c'est ce que j'avais fait au départ, mais... Les jointures sur des gros fichiers ne sont pas le fort de HFCS. Tout du moins la base que nous utilisons. Les perfs sont non seulement lamentables mais en plus, ça empêche les collègues de bosser.

    Alors, j'ai découpé "en petits morceaux", cette requête qui n'est pas maousse (genre juste une jointure). Ca me permet de voir l'avancée des traitements et de vérifier que ce que je remonte est suffisamment correct (des utilisateurs ont importé/saisi des données délirantes).
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    En fait je voyais un truc du genre:
    Code windev : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    POUR TOUT FichierAparcourir
      DateMax est date
      DateMax = "20010101"
      hExecuteRequeteSQL(sdReq,DateMax)
      SI hnbEnr(sdReq) > 0 ALORS
        DateMax = sdReq
      FIN
      // Code de gestion du DateMax
      ...
    FIN
    Et dans la requête, un petit test sur la date passée en paramètre. Il n'y a pas de jointure en plus, juste un test.

    Tatayo.

  5. #5
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Merci pour ce conseil. Mais j'ai simplifié le code à l'extrême. En fait, elle ressemble plutôt à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Id,  MAX(DateCrit) AS MaxDateCrit
    FROM Table
    WHERE id IN (%1) AND crit IN (%2) AND DateCrit < '%3'
    GROUP BY Id
    Pour n id, on doit avoir au moins un crit pour lequel la DateCrit < date (DuJour)
    n vaut entre 2 et 10.
    Pour crit, il y a une vingtaine de valeur.
    Il y a des dates saisies qui sont délirantes (genre 01/01/2345). Certes, je pourrais mettre un BETWEEN pour les dates, mais je ne pense pas que j'y gagne vraiment.

    Le résultat va me renvoyer au max n id. Ce qui m'intéresse, c'est l'id avec le max du MaxDateCrit.

    [EDIT]
    - Après optimisation du code lors du parcours de FichierAparcourir, je tombe à environ 550 requêtes à générer/traiter. Le temps est tout à fait acceptable (50 secondes environ).
    - Je passe en résolu (la question de départ n'était pas l'optimisation de la requête)

    Merci d'avoir pris le temps de lire ma prose.
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  6. #6
    Membre extrêmement actif Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Avril 2011
    Messages
    4 384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2011
    Messages : 4 384
    Points : 9 751
    Points
    9 751
    Par défaut
    Pardon, d'arriver après la bataille, mais y a un truc que je ne comprends pas.

    Quel est l'intérêt de déclarer une variable au sein d'une boucle, plutôt que la déclarer à l'extérieur, c'est à dire une seule fois !

    JS
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  7. #7
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 057
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 057
    Points : 9 396
    Points
    9 396
    Par défaut
    De manière générale, quand on peut faire une seule requête plutôt que 50 ou 200000, on est gagnant.
    Je ne sais pas si cette syntaxe est acceptée par HFSQL, et je ne sais pas non plus si c'est bien le besoin, mais je propose :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Update Table
    set DateCrit = Maxd 
    where (id, DateCrit) in 
    ( 
      SELECT Id,  MAX(DateCrit) AS MaxDateCrit  
      FROM Table
      WHERE id IN (%1) AND crit IN (%2) AND DateCrit < '%3'
      GROUP BY Id
    )
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Si tu cherches l'id avec la date max, le mieux serait de trier la requête sur la date, et de ne lire que la première ligne.
    Ou de revoir la requête pour ne renvoyer qu'une ligne. Escartefigue nous a fait un article sur ce genre de requête.

    Tatayo.

  9. #9
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Citation Envoyé par Jon Shannow Voir le message
    Pardon, d'arriver après la bataille, mais y a un truc que je ne comprends pas.

    Quel est l'intérêt de déclarer une variable au sein d'une boucle, plutôt que la déclarer à l'extérieur, c'est à dire une seule fois !

    JS
    Hello Jon,
    C'était la question de départ

    Je pense la même chose, mais le W-Langage, pour ressembler aux langages dans l'air du temps, pique des idées à ceux-ci. Cela inclut donc les variables à portée locale (dans une condition, une boucle). Autant, dans une condition, elle est déclarée une seule fois, autant pour une boucle, c'est n fois (dans mon cas 200 000 fois).

    Addendum : Pour (me) répondre, je me suis aperçu que vu le nombre de boucles à effectuer (il y en a finalement 200 000), je gagne quelques secondes sur un premier échantillon de 10 000. Logiquement, à la fin, je devrais être sur quelques minutes car le temps de traitement total estimé est de plus de 40 minutes.

    @tatayo : Concernant la proposition de tri, elle est très bonne. Cela m'évite de faire la boucle sur le résultat. Je n'y avais pas pensé sur le coup mais je pense que j'y serai venu. Merci à toi

    @tbc92 : Connaissant le SQL HF, je ne me hasarderai pas la dessus. Même si ton idée est très bonne. Merci à toi également pour cette proposition.

    Pour préciser : au départ, j'avais fait une requête unique et filtré sur le résultat. Sauf que comme je l'avais précisé en premier lieu, l'exécution pénalise les utilisateurs, est très lente (voire plante le serveur). Ma solution est "belle" mais ça a le mérite de fonctionner...
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  10. #10
    Membre éclairé
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2002
    Messages
    468
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 468
    Points : 809
    Points
    809
    Par défaut
    Ma question tombe peut être à plat, mais pour optimiser tout ça, est ce qu'une utilisation des tâches parallèles ne serait pas pertinente ?

  11. #11
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Bonjour,

    @kuranes : c'est une piste que je n'ai pas explorée du tout. Les perfs du serveur sont assez aléatoires, et je doute que d'envoyer 200 000 requêtes en "simultané" soient gérables par la bête. Mais merci pour cette idée.

    La solution que j'ai retenue :
    - Pour me répondre à ma question que je m'ai posée : Sauf cas exceptionnel (dans une condition notamment), je déclare mes variables en début de bloc de code !
    - Pour ce qui est de mon code proprement dit, je fais 3 parcours globaux : un pour fichierAParcourir => tableau associatif, un pour ma requête (sans ma clause Id IN) => tableau associatif, un pour chercher la correspondance entre les 2 tableaux associatifs.

    J'arrive à des perfs plus que convenables.

    Merci à vous tous
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 01/01/2016, 18h31
  2. Quelle langage pour une application locale mono utilisateur
    Par alaplante dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 16/02/2015, 22h49
  3. Forcer le Type d'une Variable Locale pour la Complétion de Code
    Par ShaiLeTroll dans le forum Zend Studio
    Réponses: 6
    Dernier message: 28/10/2010, 17h54
  4. [Débutant] récupération d'une variable local pour l'envoyer a un popup
    Par minogttao dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 25/11/2006, 13h58
  5. Réponses: 6
    Dernier message: 08/06/2004, 14h22

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