Snak3d0c
Snak3d0c

Reputation: 626

Why is my runspace not faster than a sequential approach?

I stumbled upon runspaces earlier this week when i was creating a WPF GUI. So now that i know of its existence, i would like to get the basics down. I found the following example https://gist.github.com/proxb/803fee30f0df244fd850 and modified it slightly (barely).

$w = [system.diagnostics.stopwatch]::startNew()
$Computers = “e”,”f”,”g”,”d”,”c”
$RunspaceCollection = @()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
$RunspacePool.Open()

$ScriptBlock = {
    Param($Computer)
    gci $computer":" -Recurse  | out-file c:\temp\t\$computer.txt

} #/ScriptBlock

Foreach ($Computer in $Computers) {
    $Powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($Computer)
    $Powershell.RunspacePool = $RunspacePool

    [Collections.Arraylist]$RunspaceCollection += New-Object -TypeName PSObject -Property @{
        Runspace = $PowerShell.BeginInvoke()
        PowerShell = $PowerShell  
    } #/New-Object
$RunspaceCollection
} #/ForEach

$w.elapsed
Write-Host "end"

So this goes through all my disks and does a get-childitem (recurse) on them and saves the output to a txt-file. But i almost have no gain in speed compared to :

$w = [system.diagnostics.stopwatch]::startNew()
$Computers = “e”,”f”,”g”,”d”,”c”
Foreach ($Computer in $Computers) {
gci $computer":" -Recurse  | out-file c:\temp\t\$computer.txt
}
$w.elapsed
Write-Host "end"

Could someone explain why this isn't faster? I can see that my txt-files are all getting created as soon as i start the script, so the runspaces do work.

I would have thought it would give me more gain in time than it does. Atm, it only gains 1 to 3 seconds at the very best, one time it was even slower than "the old way".

Upvotes: 2

Views: 392

Answers (1)

Snak3d0c
Snak3d0c

Reputation: 626

So looks like user 4c74356b41 is correct. I earlier made the same thought process and added a for-loop of 3 to it, but it seems that this wasn't enough. If i add a for-loop of a 100, the difference in performance becomes way more clear.

$w = [system.diagnostics.stopwatch]::startNew()
    $Computers = “e”,”f”,”d”,”c”
    $RunspaceCollection = @()
    $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,5)
    $RunspacePool.Open()

    $ScriptBlock = {
        Param($Computer)
    $f = get-date -format "ddmmyyyyfff"
        gci $computer":" -Recurse  | out-file c:\temp\t\$computer$f.txt
    } #/ScriptBlock
for($i = 0; $i -le 100; $i++){
$i
    Foreach ($Computer in $Computers) {
        $Powershell = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($Computer)
        $Powershell.RunspacePool = $RunspacePool

        [Collections.Arraylist]$RunspaceCollection += New-Object -TypeName PSObject -Property @{
            Runspace = $PowerShell.BeginInvoke()
            PowerShell = $PowerShell  
        } #/New-Object
    } #/ForEach
}

    While($RunspaceCollection) {    
    # Just a simple ForEach loop for each Runspace to get resolved
    Foreach ($Runspace in $RunspaceCollection.ToArray()) {

        # Here's where we actually check if the Runspace has completed
        If ($Runspace.Runspace.IsCompleted) {       
            # Here's where we cleanup our Runspace
            $Runspace.PowerShell.Dispose()
            $RunspaceCollection.Remove($Runspace)       
        } #/If
    } #/ForEach

} #/While

   $w.elapsed
Write-Host "end"

this will take:

Minutes : 4 Seconds : 23 Milliseconds : 273

where as

$w = [system.diagnostics.stopwatch]::startNew()
$Computers = “e”,”f”,”d”,”c”
for($i = 0; $i -le 100; $i++){
$i
Foreach ($Computer in $Computers) {
    $f = get-date -format "ddmmyyyyfff"
    gci $computer":" -Recurse  | out-file c:\temp\t\$computer$f.txt
    $w.elapsed
}
}
$w.elapsed
Write-Host "end 100 times"

will take

Minutes : 9 Seconds : 38 Milliseconds : 932

Upvotes: 2

Related Questions