2013-02-25 1 views
0

매우 큰 서버에서 사용하기 위해 다음 코드의 속도를 높이는 방법이 필요합니다. 필요한 것은 fullname 매개 변수의 목록입니다. 내가 좋아하는 뭔가를 사용하고자하는 다음 http://newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/Powershell GCI, 깊이 속도

어떻게 그것에 대해 읽고 있던 그것은 아주 간단 보인다, 그러나 나는 스레드가 기존 풀에 새로운 스레드를 만들 수 있도록 주위에 내 머리를 정리하고 수 없습니다 ... 그리고 그 수영장을 따라 가라.

어떤 도움도 좋을 것입니다. 왜냐하면이 속도는 끔찍하고 더 많은 자원을 가지고 있기 때문입니다.

Function Get-ChildItemToDepth { 
    Param(  
     [String]$Path = $PWD,  
     [int]$ToDepth = 255,  
     [Byte]$CurrentDepth = 0 
    ) 
    if ($ToDepth -lt 0) { 
     return get-item $path 
    } 
    $CurrentDepth++ 
    Get-ChildItem $Path | Where-Object { $_.PSIsContainer } | %{ $_ 
     If ($CurrentDepth -le $ToDepth) { 
      Get-ChildItemToDepth -Path $_.FullName ` 
      -ToDepth $ToDepth -CurrentDepth $CurrentDepth 
     } 
    } 
} 

참고 : 나는 2.0에

요약을 제한하고있다 : 나는 기본적으로 빨리 배열로 같은 디지털 가능 $ 깊이까지의 모든 폴더의 경로를해야합니다.

MISSERABLE 실패 시도 :

$func = ` 
{ 
    Param(  
     [String]$Path = $PWD,  
     [int]$ToDepth = 255,  
     [Byte]$CurrentDepth = 0, 
     $p = $pool 
    ) 
    if ($ToDepth -lt 0) { 
     return $path 
    } 
    $CurrentDepth++ 
    $folders = Get-ChildItem $Path | Where-Object { $_.PSIsContainer } | select -expand FullName 
    If ($CurrentDepth -le $ToDepth) { 
     foreach ($path in $folders) { 
      $pipeline = [System.Management.Automation.PowerShell]::create() 
      $pipeline.RunspacePool = $pool 
      $pipeline.AddScript($func).AddArgument($path).AddArgument($ToDepth).AddArgument($CurrentDepth).AddArgument($pool) 
      $AsyncHandle = $pipeline.BeginInvoke() 
      $folders += $pipeline.EndInvoke($AsyncHandle) 
      $pipeline.Dispose() 
     } 
    } 
    return $folders 
}  

$path = "\\server\users-folder\" 
$toDepth = 3 

$pool = [RunspaceFactory]::CreateRunspacePool(1, 4) 
$pool.ApartmentState = "STA" 
$pool.Open() 
$pipeline = [System.Management.Automation.PowerShell]::create() 
$pipeline.RunspacePool = $pool 
$pipeline.AddScript($func).AddArgument($path).AddArgument($toDepth).AddArgument($CurrentDepth).AddArgument($pool) 
$AsyncHandle = $pipeline.BeginInvoke() 
$RESULTS = $pipeline.EndInvoke($AsyncHandle) 
$pipeline.Dispose() 
$pool.Close() 
+0

, 나는 찬성 얻을-ChildItem을 포기 것 레거시 디렉터. cmd/c dir /b/ad/s는 gci보다 훨씬 빠르게 디렉토리 경로 목록을 반환합니다. – mjolinor

+0

덕분에 약간 도움이 될 것입니다. – TetraFlash

+0

레거시 디렉터리는 특정 디렉토리에서 풀 패스로 폴더를 가져 오지 않을 것이며/s는 적절한 경로 이름을 제공하지만 특정 깊이에서 멈추지 않습니다. 관련 하위 폴더가 실제로 더 빠릅니까? – TetraFlash

답변

0

http://psasync.codeplex.com로 이동하여 다운로드 (당신이 세션으로 워크 플로우를 붙여 넣은 후) 나는 파이프 함수의 결과는

Get-ChildItemToDepth | Measure 
Invoke-Function | Measure 

사용을 측정하는 것 psasync 모듈 (설명서는 여기 http://newsqlblog.com/2012/12/17/psasync-module-multithreaded-powershell/). 그리고 ...

Import-Module psasync 

$AsyncPipelines = @() 

# Allow 4 concurrent processes ... adjust up/down as hardware allows 
$pool = Get-RunspacePool 4 

# You can play with this to get better performance by going deeper into the directory structure to populate more dirs in the array 
# gross generalization -> more dirs + more runspaces in $pool = faster performance 

$rootDirs = Get-ChildItem c:\ | Where-Object{$_.PSIsContainer} 

# Create a script block to run code per directory stored in $rootDirs 
$ScriptBlock = { ` 
    Param(  
     [String]$Path = $path 
    ) 
    Get-ChildItem $path -recurse | Where-Object{$_.PSIsContainer} 

} 

# Load up processes on the runspace pool 
foreach($dir in $rootDirs) { 
    $AsyncPipelines += Invoke-Async -RunspacePool $pool -ScriptBlock $ScriptBlock -Parameters $dir.FullName 
} 

# "Listen" to the pipelines and grab the results 
$dirs = Receive-AsyncResults -Pipelines $AsyncPipelines 

# PROFIT 
$dirs | Foreach-Object{$_.FullName} 

덕분 newsqlblog.com 읽는)가 큰 디렉토리 구조, 그리고 다시 필요가 전체 이름 문자열 인 경우

1

시도 워크 플로에서 이것을 호출 할 - 사용할 수있는 강력한 네이티브 파워 쉘 멀티 스레딩 솔루션을 상자에서 꺼내 PowerShell을 3.0

Workflow Invoke-Function 
{ 
Function Get-ChildItemToDepth { 
    Param(  
     [String]$Path = $PWD,  
     [int]$ToDepth = 255,  
     [Byte]$CurrentDepth = 0 
    ) 
    if ($ToDepth -lt 0) { 
     return $path 
    } 
    $CurrentDepth++ 
    Get-ChildItem $Path | Where-Object { $_.PSIsContainer } | %{ $_ 
     If ($CurrentDepth -le $ToDepth) { 
      Get-ChildItemToDepth -Path $_.FullName ` 
      -ToDepth $ToDepth -CurrentDepth $CurrentDepth 
     } 
    } 
} 
Get-ChildItemToDepth 
} 

이 꽤 지저분 구현 , 난 그냥 워크 플로 주위에 당신의 기능과 전화를 싸서 그래서 당신은 쉽게 테스트를 위해 세션에 복사 붙여 넣을 수 있습니다. 그게 어떻게 효과가 있는지 알려주세요. 당신은 속도의 차이를 보려면

Invoke-Function 
+0

불행히도 나는 v2.0에 붙어있다 – TetraFlash

+0

나는 그것을 아주 유감스럽게 생각한다. –