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

Scripts/Batch Discussion :

Optimisation dans boucle


Sujet :

Scripts/Batch

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut Optimisation dans boucle
    Bonjour,

    Je cherche à optimiser le temps de traitement.
    Je suis passé de 2h30 à 1h puis 30 min.
    Je me demande s'il y a mieux à faire.

    Code Powershell : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    Function ParseData
    {
        param
        (
            [string][Parameter(Mandatory=$True)] [string]$path
        )
     
        $results = @() 
        $refresh =  [system.diagnostics.stopwatch]::StartNew()
        $clock   =  [system.diagnostics.stopwatch]::StartNew()  
        $data         = Import-Csv -Path $path -Encoding 'UTF8' -Delimiter ';'
        $data_raw  = $data.NOM | Sort
        $data_uni  = $data_raw     | Sort -Unique
        $index_max = $data_uni.Count ; Write-Host "Nombre d'entrées : $index_max"
     
        $t = Measure-Command {
            $current_index = 0;
            foreach ( $item_1 in $data_uni ) 
            { 
                $occurrences = 0  
                $results_item = @()
     
                $t_loop = Measure-Command {
                    foreach ( $item_2 in $data_raw ) 
                    { 
                        if ( $item_2 -match $item_1 ) 
                        { 
                            $occurrences++
                            $results_item += $item_2
                        }
                    }
                }
     
                $t_end = New-TimeSpan -Seconds $($index_max*$t_loop.TotalSeconds-$Clock.Elapsed.TotalSeconds)
     
                if ( $($refresh.Elapsed.TotalSeconds) -gt 10)
                {
                    $refresh.Reset() ; $refresh.Start()
                    $progress    = [Math]::Round(100*($current_index)/$index_max,1) ; 
                    Write-Host " + Progress : $progress `% - $current_index/$index_max"
                    Write-Host " | Temps sous boucle : $($t_loop.TotalSeconds) sec" 
                    Write-Host " | Temps restant estimé : $([Int32]$t_end.TotalMinutes) min"
                    Write-Host " +----------------------------------------+"
                    $refresh++
                }
     
                if ( $occurrences -eq 17 ) { $results += @{ Commune = $item_1 ; Occurence = $occurrences ; Liste = $results_item } }
                $current_index++
            }
     
            $results = $results | % { new-object PSObject -Property $_ } | Select Commune, Occurence, Liste | sort -Descending -Property Occurence
        }
     
        $clock.Stop()
        $refresh.Stop()
        Write-Host "+ Temps d''execution : $($t.TotalMinutes) minutes"
        return $results
    }

    J'ai notamment testé ceci appliqué à mon cas mais le résultat est pire.

    Code powershell : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    Function test0
    {
        $r = @()
        foreach ( $i in 0..99 ) 
        { 
            foreach ( $j in 0..499  ) 
            { 
               $r += $i*$j
            }
        }
        return $r
    }
     
    Function test1
    {
     
        $s = {
                param( $i )
     
                $r = @()
                foreach ( $j in 0..499 ) 
                { 
                   $r += $i*$j
                }
                return $r 
        }
     
        $r = @()
        foreach ( $i in 0..99 ) {
                $r += Invoke-Command -ScriptBlock $s -ArgumentList $i
        }
     
        return $r
    }
     
    $t0 = Measure-Command { $y = test0 }
    Write-Host Total : $($t0.TotalSeconds)
    $t1 = Measure-Command { $z = test1 }
    Write-Host Total : $($t1.TotalSeconds)

    Le résultat est sans appel pourtant.

    Total : 42,597765
    Total : 0,6054444

    Merci d'avance.
    Cordialement.

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 218
    Par défaut
    Enfin un peu d'optimisation
    Je me suis contenté de ton deuxième code à benchmarker

    Code powershell : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    Function test0
    {
        $r = @()
        foreach ( $i in 0..99 ) 
        { 
            foreach ( $j in 0..499  ) 
            { 
               $r += $i*$j
            }
        }
        return $r
    }
     
    Function test1
    {
     
        $s = {
                param( $i )
     
                $r = @()
                foreach ( $j in 0..499 ) 
                { 
                   $r += $i*$j
                }
                return $r 
        }
     
        $r = @()
        foreach ( $i in 0..99 ) {
                $r += Invoke-Command -ScriptBlock $s -ArgumentList $i
        }
     
        return $r
    }
     
    Function test2
    {
        $r =  [System.Collections.ArrayList]@()
        foreach ( $i in 0..99 ) 
        { 
            foreach ( $j in 0..499  ) 
            { 
               $null = $r.Add($i*$j)
            }
        }
        return $r
    }
     
    Function test3
    {
        $r = 0..99 | ForEach-Object {
            $i=$_
            0..499 | ForEach-Object {
                $i*$_
            }
        }
     
        return $r
    }
     
    $t0 = Measure-Command { $y = test0 }
    Write-Host Total : $($t0.TotalSeconds)
    $t1 = Measure-Command { $z = test1 }
    Write-Host Total : $($t1.TotalSeconds)
    $t2 = Measure-Command { $a = test2 }
    Write-Host Total : $($t2.TotalSeconds)
    $t3 = Measure-Command { $b = test3 }
    Write-Host Total : $($t3.TotalSeconds)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Total : 36,3621495
    Total : 0,545394
    Total : 0,0149748
    Total : 0,2530368

  3. #3
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    Merci pour ce retour.

    En faisant des tests avec ces méthodes, j'en viens à la conclusion que l'opération couteuse dans ce test est l'ajout de la valeur au tableau et non le parcours de la boucle ou le calcul de la multiplication.
    Or dans mon cas, cette opération étant négligeable en temps par rapport à l'opération de test de la chaine, je n'obtiens pas d'amélioration.
    Ce qu'il faudrait travailler c'est l'opération de comparaison des chaines ou trouver une structure de données plus performante qu'un system array qui stocke le fichier csv ( 35k lignes ) j'imagine.
    Par ailleurs, il me semblait que match était plus rapide que like '*pattern*' mais forcé de constater que match est 10% plus lent dans mon cas environ.

  4. #4
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 218
    Par défaut
    Me re-voila, est il possible d'avoir le csv pour tester.

    Et du coup si tu peux essayer d'expliquer ce que tu cherche à faire/obtenir.

Discussions similaires

  1. [MySQL] Requete dans boucle et optimisation
    Par freestyle83 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 06/02/2014, 18h53
  2. optimiser une boucle while imbriquer dans une boucle for
    Par bakaratoun dans le forum MATLAB
    Réponses: 0
    Dernier message: 28/01/2010, 15h35
  3. Réponses: 4
    Dernier message: 17/01/2006, 19h17
  4. [JLabel] JLabel dans boucle for
    Par clairenes dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 06/01/2006, 00h47
  5. Réponses: 12
    Dernier message: 10/11/2005, 09h05

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