มีวิธีง่ายๆในการดำเนินการคำสั่งใน PowerShell เช่นคำสั่ง 'time' ใน Linux หรือไม่?
ฉันมากับสิ่งนี้:
$s=Get-Date; .\do_something.ps1 ; $e=Get-Date; ($e - $s).TotalSeconds
แต่ฉันต้องการบางสิ่งที่ง่ายกว่าเช่น
time .\do_something.ps1
มีวิธีง่ายๆในการดำเนินการคำสั่งใน PowerShell เช่นคำสั่ง 'time' ใน Linux หรือไม่?
ฉันมากับสิ่งนี้:
$s=Get-Date; .\do_something.ps1 ; $e=Get-Date; ($e - $s).TotalSeconds
แต่ฉันต้องการบางสิ่งที่ง่ายกว่าเช่น
time .\do_something.ps1
คำตอบ:
ได้.
Measure-Command { .\do_something.ps1 }
โปรดทราบว่าข้อเสียเล็กน้อยประการหนึ่งMeasure-Command
คือคุณไม่เห็นstdout
ผลลัพธ์
[อัปเดตขอบคุณ @JasonMArcher] คุณสามารถแก้ไขได้โดยการไพพ์เอาต์พุตคำสั่งไปยัง commandlet บางตัวที่เขียนไปยังโฮสต์เช่นOut-Default
นั้นจะกลายเป็น:
Measure-Command { .\do_something.ps1 | Out-Default }
อีกวิธีในการดูผลลัพธ์ก็คือใช้Stopwatch
คลาส. NET ดังนี้:
$sw = [Diagnostics.Stopwatch]::StartNew()
.\do_something.ps1
$sw.Stop()
$sw.Elapsed
time { ping -n 1 google.com } -Samples 10
จะรัน10
เวลาคำสั่งและคืนค่าเฉลี่ยเวลาต่ำสุดและสูงสุด คุณสามารถเพิ่มที่-Silent
จะกลืน STDOUT
$t = Measure-Command {<<your command or code block>>}
การตั้งค่าของฉันจะกำหนดผลมาจากการวัด-คำสั่งให้กับตัวแปรเช่น ลองแล้วพิมพ์$t
ที่พร้อมท์จะเห็นผลและคุณสมบัติทั้งหมดที่คุณมีการเข้าถึงเช่นคุณ$t.Milliseconds
, $t.TotalSeconds
เป็นต้นจากนั้นเราสามารถเขียนสิ่งที่เราต้องการเอาท์พุทเช่นWrite-Host That command took $t.TotalSeconds to complete.
นอกจากนี้คุณยังจะได้รับคำสั่งสุดท้ายจากประวัติศาสตร์และลบของมันจากมันEndExecutionTime
StartExecutionTime
.\do_something.ps1
$command = Get-History -Count 1
$command.EndExecutionTime - $command.StartExecutionTime
Get-History | Group {$_.StartExecutionTime.Hour} | sort Count -desc
เพื่อดูรูปแบบการใช้ PowerShell ของคุณแบบรายชั่วโมง :-)
$command = Get-History -Count 1 ; "{0}" -f ($command.EndExecutionTime - $command.StartExecutionTime)
ใช้ Measure-Command
ตัวอย่าง
Measure-Command { <your command here> | Out-Host }
ท่อที่จะช่วยให้คุณเห็นผลลัพธ์ของคำสั่งที่มีการบริโภคเป็นอย่างอื่นโดยOut-Host
Measure-Command
Measure-Command {<your command } | Out-Host
- Out-Host อยู่นอกบล็อกสคริปต์
Simples
function time($block) {
$sw = [Diagnostics.Stopwatch]::StartNew()
&$block
$sw.Stop()
$sw.Elapsed
}
จากนั้นสามารถใช้เป็น
time { .\some_command }
คุณอาจต้องการปรับแต่งเอาท์พุท
Measure-Command
ซ่อนเอาต์พุตคำสั่งดังนั้นโซลูชันนี้บางครั้งก็ดีกว่า
นี่คือฟังก์ชั่นที่ฉันเขียนซึ่งทำงานคล้ายกับ Unix time
คำสั่ง :
function time {
Param(
[Parameter(Mandatory=$true)]
[string]$command,
[switch]$quiet = $false
)
$start = Get-Date
try {
if ( -not $quiet ) {
iex $command | Write-Host
} else {
iex $command > $null
}
} finally {
$(Get-Date) - $start
}
}
ที่มา: https://gist.github.com/bender-the-greatest/741f696d965ed9728dc6287bdd336874
Measure-Command
หรือหนึ่งในวิธีอื่น ๆ ที่คุณสามารถใช้เวลาดำเนินการใน Powershell ได้ หากคุณอ่านคำถามต้นฉบับเขาจะถามถึงสิ่งที่ใช้ได้ "เหมือนtime
คำสั่งใน Linux"
การใช้นาฬิกาจับเวลาและการจัดรูปแบบเวลาที่ผ่านไป:
Function FormatElapsedTime($ts)
{
$elapsedTime = ""
if ( $ts.Minutes -gt 0 )
{
$elapsedTime = [string]::Format( "{0:00} min. {1:00}.{2:00} sec.", $ts.Minutes, $ts.Seconds, $ts.Milliseconds / 10 );
}
else
{
$elapsedTime = [string]::Format( "{0:00}.{1:00} sec.", $ts.Seconds, $ts.Milliseconds / 10 );
}
if ($ts.Hours -eq 0 -and $ts.Minutes -eq 0 -and $ts.Seconds -eq 0)
{
$elapsedTime = [string]::Format("{0:00} ms.", $ts.Milliseconds);
}
if ($ts.Milliseconds -eq 0)
{
$elapsedTime = [string]::Format("{0} ms", $ts.TotalMilliseconds);
}
return $elapsedTime
}
Function StepTimeBlock($step, $block)
{
Write-Host "`r`n*****"
Write-Host $step
Write-Host "`r`n*****"
$sw = [Diagnostics.Stopwatch]::StartNew()
&$block
$sw.Stop()
$time = $sw.Elapsed
$formatTime = FormatElapsedTime $time
Write-Host "`r`n`t=====> $step took $formatTime"
}
ตัวอย่างการใช้งาน
StepTimeBlock ("Publish {0} Reports" -f $Script:ArrayReportsList.Count) {
$Script:ArrayReportsList | % { Publish-Report $WebServiceSSRSRDL $_ $CarpetaReports $CarpetaDataSources $Script:datasourceReport };
}
StepTimeBlock ("My Process") { .\do_something.ps1 }
ข้อสรุปในรูปวาด (ไม่ถูกต้อง) จากคำสั่งการวัดประสิทธิภาพที่อ้างถึงในคำตอบ มีข้อผิดพลาดหลายประการที่ควรพิจารณานอกเหนือจากการมองไปที่เวลาร้องขอการเปลือยของฟังก์ชันหรือคำสั่ง (กำหนดเอง)
'Sjoemelsoftware' โหวตให้ชาวดัตช์คำในปี 2015
Sjoemelenหมายถึงการโกงและคำว่า sjoemelsoftwareเกิดขึ้นเนื่องจากเรื่องอื้อฉาวการปล่อยมลพิษของโฟล์คสวาเกน คำจำกัดความอย่างเป็นทางการคือ "ซอฟต์แวร์ที่ใช้เพื่อมีอิทธิพลต่อผลการทดสอบ"
ส่วนตัวผมคิดว่า " Sjoemelsoftware " ไม่ได้ถูกสร้างขึ้นโดยเจตนาเพื่อโกงผลการทดสอบ แต่อาจเกิดจากการช่วยเหลือในสถานการณ์จริงที่คล้ายกับกรณีทดสอบดังที่แสดงด้านล่าง
เป็นตัวอย่างการใช้คำสั่งการวัดประสิทธิภาพในรายการภาษา Integrated Query (LINQ) (1)มักจะมีคุณสมบัติเป็นวิธี Fasted ที่จะได้รับสิ่งที่ทำและมันมักจะเป็น แต่ไม่แน่นอนเสมอ! ใครก็ตามที่วัดการเพิ่มความเร็วของปัจจัย 40 หรือมากกว่าเมื่อเปรียบเทียบกับคำสั่ง PowerShell ดั้งเดิมอาจเป็นการวัดหรือวาดข้อสรุปที่ไม่ถูกต้องอย่างไม่ถูกต้อง
ประเด็นคือคลาส. Net บางคลาส (เช่น LINQ) ใช้การประเมินแบบสันหลังยาว (หรือเรียกอีกอย่างว่าการประมวลผลที่เลื่อนออกไป(2) ) หมายความว่าเมื่อกำหนดนิพจน์ให้กับตัวแปรมันเกือบจะปรากฏขึ้นทันที แต่ในความเป็นจริงมันยังไม่ได้ประมวลผลอะไรเลย!
สมมติว่าคุณdot-source. .\Dosomething.ps1
คำสั่งของคุณซึ่งมี PowerShell หรือนิพจน์ Linq ที่ซับซ้อนยิ่งขึ้น (เพื่อความสะดวกในการอธิบายฉันได้ฝังการแสดงออกโดยตรงลงในMeasure-Command
)
$Data = @(1..100000).ForEach{[PSCustomObject]@{Index=$_;Property=(Get-Random)}}
(Measure-Command {
$PowerShell = $Data.Where{$_.Index -eq 12345}
}).totalmilliseconds
864.5237
(Measure-Command {
$Linq = [Linq.Enumerable]::Where($Data, [Func[object,bool]] { param($Item); Return $Item.Index -eq 12345})
}).totalmilliseconds
24.5949
ผลลัพธ์ปรากฏชัดเจนคำสั่งLinq ในภายหลังนั้นเร็วกว่าคำสั่งPowerShellแรกประมาณ40 เท่า น่าเสียดายที่มันไม่ง่ายอย่างนั้น ...
แสดงผลลัพธ์:
PS C:\> $PowerShell
Index Property
----- --------
12345 104123841
PS C:\> $Linq
Index Property
----- --------
12345 104123841
เป็นที่คาดหวังผลเหมือนกัน แต่ถ้าคุณได้ให้ความสนใจอย่างใกล้ชิดคุณจะได้สังเกตเห็นว่ามันต้องใช้เวลานานมากในการแสดง$Linq
ผลแล้ว$PowerShell
ผล
Let 's โดยเฉพาะวัดที่โดยเพียงแค่การดึงคุณสมบัติของวัตถุผลไปนี้:
PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds
14.8798
PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds
1360.9435
ใช้เวลานานกว่า90วินาทีในการเรียกคืนคุณสมบัติของ$Linq
วัตถุจากนั้น$PowerShell
วัตถุและนั่นเป็นเพียงวัตถุเดียว!
นอกจากนี้ยังสังเกตเห็นข้อผิดพลาดอื่น ๆ ที่ถ้าคุณทำอีกครั้งขั้นตอนบางอย่างอาจปรากฏขึ้นเร็วกว่ามากก่อนหน้านี้เป็นเพราะการแสดงออกบางส่วนได้ถูกแคช
บรรทัดล่างถ้าคุณต้องการเปรียบเทียบประสิทธิภาพระหว่างสองฟังก์ชั่นคุณจะต้องนำไปใช้ในกรณีที่คุณใช้เริ่มต้นด้วยเซสชัน PowerShell ที่สดใหม่และใช้ข้อสรุปของคุณเกี่ยวกับประสิทธิภาพที่แท้จริงของโซลูชันที่สมบูรณ์
(1) สำหรับพื้นหลังเพิ่มเติมและตัวอย่างใน PowerShell และ LINQ ผมขอแนะนำเว็บไซต์ tihis: PowerShell ประสิทธิภาพสูงด้วย LINQ
(2) ผมคิดว่ามีความแตกต่างเล็ก ๆ น้อย ๆ ระหว่างสองแนวความคิดเช่นเดียวกับการประเมินผลขี้เกียจผลจะคำนวณได้เมื่อมีความจำเป็น apposed เป็นไปการดำเนินการที่ถูกเลื่อนออกไปเป็นผลลัพธ์จะถูกคำนวณเมื่อระบบไม่ได้ทำงาน