क्या PowerShell में कमांड के निष्पादन का एक सरल तरीका है, जैसे लिनक्स में 'टाइम' कमांड?
मैं इसके साथ आया:
$s=Get-Date; .\do_something.ps1 ; $e=Get-Date; ($e - $s).TotalSeconds
लेकिन मैं कुछ सरल करना चाहूंगा
time .\do_something.ps1
क्या PowerShell में कमांड के निष्पादन का एक सरल तरीका है, जैसे लिनक्स में 'टाइम' कमांड?
मैं इसके साथ आया:
$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 के लिए धन्यवाद] आप कमांड को आउटपुट से कुछ कमांडलेट तक होस्ट करके लिखते हैं, जैसे Out-Default
कि यह हो जाता है , इसे ठीक कर सकते हैं :
Measure-Command { .\do_something.ps1 | Out-Default }
आउटपुट को देखने का एक अन्य तरीका .NET Stopwatch
क्लास का इस तरह उपयोग करना होगा :
$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
अपने पॉवरशेल उपयोग पैटर्न को दिन के घंटे के हिसाब से देखें। :-)
$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
- आउट-होस्ट स्क्रिप्ट ब्लॉक के बाहर है
साधारण
function time($block) {
$sw = [Diagnostics.Stopwatch]::StartNew()
&$block
$sw.Stop()
$sw.Elapsed
}
तो के रूप में उपयोग कर सकते हैं
time { .\some_command }
आप आउटपुट को ट्विक करना चाह सकते हैं
Measure-Command
कमांड आउटपुट को छुपाता है, इसलिए यह समाधान कभी-कभी बेहतर होता है।
यहां मैंने एक फ़ंक्शन लिखा है जो यूनिक्स 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
या विभिन्न अन्य तरीकों में से एक है जिसका आप पॉवर्सशेल में निष्पादन कर सकते हैं। यदि आप मूल प्रश्न को पढ़ते हैं, तो उसने " time
लिनक्स में कमांड की तरह" काम करने वाली चीज़ मांगी ।
स्टॉपवॉच और स्वरूपित समय का उपयोग करना:
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 " हमेशा जानबूझकर परीक्षा परिणामों को धोखा देने के लिए नहीं बनाया गया है, लेकिन व्यावहारिक स्थिति को समायोजित करने से उत्पन्न हो सकता है जो नीचे दिखाए गए मामलों के समान हैं।
एक उदाहरण के रूप में, सूचीबद्ध प्रदर्शन माप आदेशों का उपयोग करते हुए, भाषा एकीकृत क्वेरी (LINQ) (1) , अक्सर कुछ करने के लिए उपवास के तरीके के रूप में योग्य है और यह अक्सर होता है, लेकिन निश्चित रूप से हमेशा नहीं! कोई भी जो देशी PowerShell कमांड की तुलना में एक कारक 40 या उससे अधिक की गति वृद्धि को मापता है , शायद गलत निष्कर्ष को गलत तरीके से माप या आरेखण कर रहा है।
मुद्दा यह है कि कुछ .Net कक्षाएं (LINQ की तरह) एक आलसी मूल्यांकन का उपयोग करती हैं (जिसे आस्थगित निष्पादन (2) भी कहा जाता है )। इसका मतलब है कि जब एक चर के लिए एक अभिव्यक्ति प्रदान करते हैं, तो यह लगभग तुरंत ही प्रतीत होता है लेकिन वास्तव में यह अभी तक कुछ भी संसाधित नहीं करता है!
मान लें कि आपने अपनी कमांड को डॉट-सोर्स. .\Dosomething.ps1
किया है, जिसमें या तो पावरशेल है या अधिक परिष्कृत लाइनक एक्सप्रेशन है (स्पष्टीकरण में आसानी के लिए, मैंने सीधे एक्सप्रेशंस को सीधे एंबेड किया है 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
।
आइए विशेष रूप से मापें कि परिणामी वस्तु की संपत्ति को पुनः प्राप्त करके:
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 पर अधिक पृष्ठभूमि और उदाहरणों के लिए, मैं टिहिस साइट की सलाह देता हूं: LINQ के साथ उच्च प्रदर्शन पॉवरशेल
(2) मुझे लगता है कि दो अवधारणाओं के बीच एक मामूली अंतर है क्योंकि आलसी मूल्यांकन के साथ परिणाम की गणना तब की जाती है जब इसे एप्लाय किया जाता है। आस्थगित निष्पादन थे परिणाम की गणना तब की जाती है जब सिस्टम निष्क्रिय होता है