PowerShell 성능 차이 필터와 기능


11

PowerShell에 대한 통찰력을 얻으려면 현재 Windows PowerShell 3.0 단계별 책을 읽고 있습니다.

201 페이지에서 저자는 필터가 기능적으로 같은 기능보다 빠르다는 것을 보여줍니다.

이 스크립트는 컴퓨터에서 2.6 초가 걸립니다.

MeasureAddOneFilter.ps1
Filter AddOne
{ 
 "add one filter"
  $_ + 1
}

Measure-Command { 1..50000 | addOne }

이 4.6 초

MeasureAddOneFunction.ps1
Function AddOne
{  
  "Add One Function"
  While ($input.moveNext())
   {
     $input.current + 1
   }
}

Measure-Command { 1..50000 | addOne }

이 코드를 실행하면 그의 결과와 완전히 반대입니다.

.\MeasureAddOneFilter.ps1
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 226
Ticks             : 2266171
TotalDays         : 2,62288310185185E-06
TotalHours        : 6,29491944444444E-05
TotalMinutes      : 0,00377695166666667
TotalSeconds      : 0,2266171
TotalMilliseconds : 226,6171

.\MeasureAddOneFunction.ps1

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 93
Ticks             : 933649
TotalDays         : 1,08061226851852E-06
TotalHours        : 2,59346944444444E-05
TotalMinutes      : 0,00155608166666667
TotalSeconds      : 0,0933649
TotalMilliseconds : 93,3649

누군가 나에게 이것을 설명 할 수 있습니까?

답변:


13

저자가 더 많은 증거를 제시하지 않는 한, 그는 아마도 열기로 가득 차 있었을 것입니다. 당신은 테스트를 실행하고 결과를 얻었고 그를 잘못 입증했습니다.

편집 : Jeffrey Snover의 블로그에서 :

필터는 프로세스 스크립트 블록 만있는 함수입니다.

그것만으로는 필터가 동일한 프로세스 블록을 가지고 있다고 가정 할 때 필터가 기능보다 속도 이점을 가질 것이라고 확신하기에 충분하지 않습니다.

또한 1950 년대의 장비는 숫자에 1을 더하는 데 4.6 초가 걸리는 곳입니까?

PS C:\Users\Ryan> Measure-Command { Filter AddOne { $_ + 1 }; AddOne 1 }

TotalMilliseconds : 7.7266


PS C:\Users\Ryan> Measure-Command { Function AddOne { $_ + 1 }; AddOne 1 }    

TotalMilliseconds : 0.4108

4.6 초입니다. 아마도 저자는 바이너리가 생성되기 전에 일종의 CTP 버전의 Powershell을 사용하고 있었을 것입니다. :피

마지막으로, 새로운 Powershell 세션에서 테스트를 역순으로 시도하십시오. 기능을 먼저 시도하고 필터를 두 번째로 시도하십시오.

PS C:\Users\Ryan> Measure-Command { Function AddOne { $_ + 1 }; AddOne 1 }    

TotalMilliseconds : 6.597    


PS C:\Users\Ryan> Measure-Command { Filter AddOne { $_ + 1 }; AddOne 1 }

TotalMilliseconds : 0.4055

보다? 첫 번째 실행은 항상 느립니다. 함수 또는 필터에 관계없이 두 번째 작업을 더 빠르게 수행하는 메모리에 이미로드 된 내용은 .NET 내부에 관한 것입니다.

나는 함수가 몇 번이나 실행되는지에 관계없이 함수가 필터보다 일관되게 더 빠르다는 것을 인정합니다.

Measure-Command { Function AddOne($Num) { Return $Num += 1 }; 1..50000 | AddOne $_ }

TotalMilliseconds : 13.9813

Measure-Command { Filter AddOne($Num) { Return $Num += 1 }; 1..50000 | AddOne $_ }

TotalMilliseconds : 69.5301

그래서 저자는 잘못되었습니다 ... 이제는 함수 대신 필터를 사용한 적이 결코 나쁘지 않습니다.


4

두 테스트에서 동일한 $ _를 사용하면 실제로 차이가 훨씬 작습니다. 나는 원인을 조사하지 않았지만 저자가 두 테스트에서 동일한 접근 방식을 사용하지 않기 때문이라고 생각합니다. 또한 콘솔 출력이 결과를 방해 할 수 있습니다. 이 부분을 자르면 숫자가 매우 비슷합니다. 보다:

Function AddOneFunction
{  
    process {
        $_ + 1
    }
}

Filter AddOneFilter
{ 
    $_ + 1
}

write-host "First"
Measure-Command { 1..50000 | AddOneFilter } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFilter } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFilter } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFilter } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFilter } | select totalMilliseconds

write-host "Second"
Measure-Command { 1..50000 | AddOneFunction } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFunction } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFunction } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFunction } | select totalMilliseconds
Measure-Command { 1..50000 | AddOneFunction } | select totalMilliseconds

명령 순서를 변경하더라도 결과는 매우 가깝습니다.

First

TotalMilliseconds
-----------------
        84.6742
        84.7646
        89.8603
        82.3399
        83.8195
Second
        86.8978
        87.4064
        89.304
        94.4334
        87.0135

문서는 또한 필터는 기본적으로 프로세스 블록 만있는 기능에 대한 바로 가기라고 말합니다. 프로세스 블록 (또는 $ input과 같은 자동 변수 사용과 같은 다른 기술)으로 지정되지 않은 한 함수는 한 번 실행되고 입력을 사용하지 않으며 파이프 라인의 다음 명령으로 전달되지 않습니다.

https://technet.microsoft.com/en-us/library/hh847829.aspxhttps://technet.microsoft.com/en-us/library/hh847781.aspx에 대한 자세한 정보

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.