Question
\"pipes\" et \"threads\": fonctionnement de powershell
- bamade
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 14
- Remerciements reçus 0
Si je me la pose c'est que je viens des scripts UNIX (pas taper! pas taper!
Un exemple pour comprendre :
[code:1]
# exemple 1 : avec tubage
Get-ChildItem \"C:\Program Files\" -recurse | where {$_.extension -eq \".exe\"}
[/code:1]
et un autre :
[code:1]
#exemple 2: variable de stockage stupide
$fichiers = Get-ChildItem \"C:\Program Files\" -recurse
$fichiers | where {$_.extension -eq \".exe\"}
[/code:1]
Il me semble (mais je peux me tromper) que exemple 1 doit être plus performant/souhaitable si ....
Si chaque code qui fait partie d'un tube a un fonctionnement \"en parallèle\" (Thread natif, ou émulation -green_thread-) [on doit avoir un fonctionnement producteur/consommateur de part et d'autre d'un \"|\": la commande à gauche n'a pas fini de s'exécuter que la commande à droite commence à turbiner]
est-ce important de savoir ça?: oui si on traite un fichier de log avec des millions d'éléments (ça existe).
Donc mesdames et messieurs qui peut me dire comment collaborent les deux parties dans un \"pipe\"?
merci
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
berber écrit:
Je trouve très intéressant d'avoir sur PowerShell des retours de personnes utilisant Unix.Si je me la pose c'est que je viens des scripts UNIX (pas taper! pas taper!
)
MS n'a rien inventé, Jeffrey Snover et 2-3 de ses collègues ont \"juste\" eu l'idée de passer des objets dans le pipe.
berber écrit:
Je suis tenté de confirmer, bien que Measure-Command fasse ça mieux que moi.Il me semble (mais je peux me tromper) que exemple 1 doit être plus performant/souhaitable si ....
Mais il faut savoir que sous PS les traitements de masse sur des fichiers peuvent être très, trop, long.
Il y a qq posts à ce sujet sur le forum, mais je ne les ai pas retrouvé.
berber écrit:
Je ne pense pas, sous PS un pipe \"héberge\" deux \"segment\" de pipeline ou une suite d'instructions.Si chaque code qui fait partie d'un tube a un fonctionnement \"en parallèle\" (Thread natif, ou émulation -green_thread-)
Là il faut voir l'objet pipeline du côté de MSDN, un pipe est exécutée au sein d'un objet Runspace qui ne peut exécuter qu'un seule pipeline à la fois, mais il existe la notion de pipeline imbriquée...
Il faut lire le SDK, voir utiliser Reflector, pour aller plus loin.
berber écrit:
C'est ce que l'équipe de PS a formulé dans ses premières présentations (2006) sur ce Shell.[on doit avoir un fonctionnement producteur/consommateur de part et d'autre d'un \"|\": la commande à gauche n'a pas fini de s'exécuter que la commande à droite commence à turbiner]
Mais, à mon avis, sans y associer la notion de thread, sous PS tout est adapté, voir le pattern Design Adapter.
berber écrit:
Exact, de toute façons PS te le rappelera indirectement sans que tu le lui demandes.est-ce important de savoir ça?: oui si on traite un fichier de log avec des millions d'éléments (ça existe).
Hé oui, dans l'adversité PS est sympa
berber écrit:
Tu peux consulter ce tutoriel , mais je ne suis pas certains qu'il réponde à toutes tes questions.Donc mesdames et messieurs qui peut me dire comment collaborent les deux parties dans un \"pipe\"?
Ensuite il faut savoir que PS c'est qq fois une boîte noire, ces derniers temps qq personnes sur le forum demandaient où trouver les specs de PowerShell, là où le C# propose + de 500 pages...
Bah c'est un mystère, et la probable réponse de collégiens contemporains ne nous aidera pas.
Pour te dire, même en étant MVP la future V3 reste 'top secret', à mon avis et tout comptes fait, la doc, c'est LE problème sur ce produit !
Bienvenue au club.<br><br>Message édité par: Laurent Dardenne, à: 10/02/11 18:30
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Jacques Barathon
- Hors Ligne
- Administrateur
-
- Messages : 576
- Remerciements reçus 0
D'une manière générale, le pipe transmet automatiquement à la commande de droite tout objet qu'il reçoit de la commande de gauche.
De ce principe de base, résulte qu'une grande partie de l'efficacité du process dépend de la façon dont les commandes transmettent leurs objets. Si une commande a tendance à ne transmettre ses objets que par lots, voire en un seul lot en fin de traitement, le pipe ne pourra pas faire mieux que d'attendre d'avoir reçu le lot avant de le transmettre.
Maintenant, dans l'exemple que tu donnes, dans les deux cas le pipe reçoit les objets un à un. $fichiers est une collection d'objets reconnue comme telle par PS, il émet donc bien les objets vers le pipe et donc vers la commande suivante au fur et à mesure où il les lit. De ce point de vue-là, cette façon de faire n'est pas moins optimale que la première.
La 2e méthode a surtout comme inconvénients de :
a) monopoliser en mémoire l'espace nécessaire pour stocker $fichiers (alors que dans la 1e méthode, seuls les objets en cours de traitement par le pipe - pour faire simple - monopolisent de la mémoire)
b) différer l'affichage du résultat en toute fin de traitement. En effet, ici le plus long traitement est celui qui consiste à parcourir le disque (get-childitem etc). La partie de lecture des résultats et de filtrage sur les .exe n'est qu'une simple formalité.
On retrouve la même problématique dans les différences entre les deux foreach - le mot-clé foreach et la commande foreach-object :
[code:1]
# mot-clé foreach :
$exe = 0
foreach ($file in get-childitem \"C:\Program Files\" -rec)
{
if ($file.extension -eq \".exe\"«») {$_; $exe++}
}
\"Nombre de fichiers .exe : {0}\" -f $exe
# Commande foreach-object :
$exe = 0
get-childitem \"C:\Program Files\" -rec | foreach {
if ($_.extension -eq \".exe\"«») {$_; $exe++}
}
\"Nombre de fichiers .exe : {0}\" -f $exe
[/code:1]
Je ne suis pas convaincu qu'on puisse prédire avec certitude si une méthode sera plus rapide qu'une autre, mais à coup sûr la deuxième consommera moins de mémoire et commencera à afficher ses résultats plus rapidement.
Pour ce qui est de PS et les gros fichiers, le problème est surtout que PS ajoute au contenu des infos propres à son contexte objet. On peut accélérer les choses en passant directement par les classes .NET.
Connexion ou Créer un compte pour participer à la conversation.
- Arthur
- Hors Ligne
- Membre elite
-
- Messages : 226
- Remerciements reçus 0
When you use Get-Content to read in text files, you may initially be disappointed by its performance. However, Get-Content is slow only because it emits each line to the pipeline as it reads the file, which is time-consuming. You can dramatically speed up reading large text files by adding the parameter -ReadCount 0 to Get-Content. This way, the file is read and only then passed on to the pipeline. Check this out:
Get-Content $env:windir\windowsupdate.log | Where-Object { $_ -like '*successfully installed*' }
$txt = Get-Content $env:windir\windowsupdate.log -ReadCount 0
$txt | Where-Object { $_ -like '*successfully installed*' }
[code:1]Measure-command { $txt = Get-Content $env:windir\windowsupdate.log -ReadCount 0; $txt | Where-Object
{ $_ -like '*successfully installed*' } }
#TotalSeconds : 0,90677
Measure-command { Get-Content $env:windir\windowsupdate.log | Where-Object { $_ -like '*successfully
installed*' } }
#TotalSeconds : 1,1284136
[/code:1]
Il me semble aussi que Powershell a du mal parfois avec les gros traitements, il est conseillé d'utiliser les bonnes classes .NET adaptés, qui sont parfois plus rapides que les cmdlet de base.<br><br>Message édité par: bilbao, à: 10/02/11 23:20
Connexion ou Créer un compte pour participer à la conversation.
- bamade
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 14
- Remerciements reçus 0
@bilbao: je trouve l'exemple cité contre-intuitif. Ou bien l'équipe powershell met en place un mécanisme de bufferisation de lecture dans le fichier, puis nous en fait profiter pour optimiser le pipe ou bien ils ont le devoir d'expliquer pourquoi un stockage dans une variable est plus optimum que de faire un traitement au fil de l'eau. On ne peut pas livrer un \"truc\" technique sans expliquer pourquoi
- edit: je viens de tester : j'ai exactement l'inverse de ce qui est annoncé les résultats sont conformes à la logique le tube \"pur\" est plus performant! en fait il y a une confusion dans l'exemple ReadCount affecte les performances globales du système de fonctionnement du tube (et donc il faut l'utiliser) mais passer par une variable intermédiaire n'est pas bon. Je soupçonne fortement la doc de ReadCount d'être mal rédigée! (en fait je pense que c'est une option de bufferisation)
@laurent dardenne: le document de specs arrive bientot (ouf!) je l'ai mentionné dans un autre post.
Message édité par: berber, à: 11/02/11 10:00<br><br>Message édité par: berber, à: 11/02/11 10:12
Connexion ou Créer un compte pour participer à la conversation.
- bamade
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 14
- Remerciements reçus 0
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- "pipes" et "threads": fonctionnement de powershell