PowerShell में एक कमांड का निष्पादन समय


217

क्या PowerShell में कमांड के निष्पादन का एक सरल तरीका है, जैसे लिनक्स में 'टाइम' कमांड?
मैं इसके साथ आया:

$s=Get-Date; .\do_something.ps1 ; $e=Get-Date; ($e - $s).TotalSeconds

लेकिन मैं कुछ सरल करना चाहूंगा

time .\do_something.ps1

जवाबों:


337

हाँ।

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

114
आप इस तरह आउटपुट भी देख सकते हैं, माप-कमान {ps | बाहर डिफ़ॉल्ट}। या कुछ और जो सीधे मेजबान को लिखता है, जो उपयोगी हो सकता है या नहीं।
जेसनमाकर

18
मैंने इसका हल निकाल लिया और एक समारोह लिखा जो किसी और के लिए उपयोगी हो सकता है। gist.github.com/2206444 - उदाहरण: time { ping -n 1 google.com } -Samples 10कमांड 10बार चलाएगा और लिया गया औसत, न्यूनतम और अधिकतम समय लौटाएगा। आप -SilentSTDOUT निगल करने के लिए जोड़ सकते हैं ।
joshuapoehls

13
मेरी प्राथमिकता माप-आदेश के परिणाम को एक चर की तरह असाइन करना होगा $t = Measure-Command {<<your command or code block>>}। इसे आजमाएं और फिर टाइप $tप्रॉम्प्ट पर अपने परिणामों को और सभी गुण आप की तरह उपयोग कर सकते है को देखने के लिए $t.Milliseconds, $t.TotalSeconds,, आदि तो हम जो कुछ भी उत्पादन हम चाहते हैं पर लिख सकते हैं, उदाहरण के लिएWrite-Host That command took $t.TotalSeconds to complete.
Baodad

क्या तेजी से उपयोग है? net.stopwatch, या माप-कमांड, या सिर्फ दो गेट-डेट वर्जन की तुलना ... (मेरा मतलब है कि एक स्क्रिप्ट में स्थायी रूप से रखने के लिए और अधिक कुशल क्या है?)
Hicsy

शायद जेसनमैचर की टिप्पणी का सार भी शामिल है (इसलिए यह स्पष्ट है कि इसे पूरी पावरस्क्रिप्‍ट की तुलना में अधिक बारीक तरीके से उपयोग किया जा सकता है)?
पीटर मोर्टेंसन

183

आप इतिहास से अंतिम आदेश भी प्राप्त कर सकते हैं और इसके EndExecutionTimeसे घटा सकते हैं StartExecutionTime

.\do_something.ps1  
$command = Get-History -Count 1  
$command.EndExecutionTime - $command.StartExecutionTime

22
इसे कुछ समय के लिए आज़माएं: Get-History | Group {$_.StartExecutionTime.Hour} | sort Count -descअपने पॉवरशेल उपयोग पैटर्न को दिन के घंटे के हिसाब से देखें। :-)
कीथ हिल

18
+1 यह जानने के लिए इसका उपयोग करने में सक्षम होने के लिए कि किसी चीज़ ने कितना समय लिया, जब आपको इसकी उम्मीद नहीं थी कि जब आप इसे शुरू करते हैं, तो आप इसे माप-कमान में लपेटने के लिए नहीं सोचते हैं।
क्रिस मैग्नसन

3
शक्तियां कभी-कभी कमाल की होती हैं।
कांस्टेंटाइनके

काश मैं आपको केवल +1 :) से अधिक दे
सकूं

हाँ, यह बहुत अच्छा है! मैंने एक-लाइनर का उपयोग किया:$command = Get-History -Count 1 ; "{0}" -f ($command.EndExecutionTime - $command.StartExecutionTime)
फिल

106

उपयोग Measure-Command

उदाहरण

Measure-Command { <your command here> | Out-Host }

पाइप Out-Hostआपको कमांड के आउटपुट को देखने की अनुमति देता है, जो अन्यथा द्वारा खपत होती है Measure-Command


मुझे लगता है कि आपका मतलब है Measure-Command {<your command } | Out-Host - आउट-होस्ट स्क्रिप्ट ब्लॉक के बाहर है
पीटर मैकएव

1
@ पेटर - इसे ब्लॉक के अंदर होना चाहिए, अन्यथा माप-कमान कंसोल पर जाने से पहले आउटपुट का उपभोग करता है।
Droj

1
समझे ... उस स्थिति में, आपको पाइप की आवश्यकता भी नहीं हो सकती है। जब तक आप इसे किसी अन्य ब्लॉक में नहीं लपेटते हैं, तब तक इसे केवल परिणाम प्रिंट करना चाहिए ....
Droj

2
क्या आउट-डिफॉल्ट शायद आउट-होस्ट से बेहतर है क्योंकि स्क्रिप्टिंग के साथ संगत है? jsnover.com/blog/2013/12/07/write-host-considered-harmful
MarcH

1
वैसे मैंने आउट-डिफॉल्ट की कोशिश की है और यह टर्मिनल में भी ठीक काम करता है, इसलिए हमेशा आउट-डिफॉल्ट का उपयोग क्यों न करें? (मैंने इसे स्क्रिप्ट सॉरी में नहीं आज़माया है)
मार्ख

18

साधारण

function time($block) {
    $sw = [Diagnostics.Stopwatch]::StartNew()
    &$block
    $sw.Stop()
    $sw.Elapsed
}

तो के रूप में उपयोग कर सकते हैं

time { .\some_command }

आप आउटपुट को ट्विक करना चाह सकते हैं


1
Measure-Commandकमांड आउटपुट को छुपाता है, इसलिए यह समाधान कभी-कभी बेहतर होता है।
कोडकइज़न

यह एक शानदार समाधान है, जो कमांड के आउटपुट का सम्मान करता है। आप इसे सरल आदेशों के लिए घुंघराले ब्रेसिज़ के बिना भी लागू कर सकते हैं, उदाहरण के लिए: "समय एलएस", ठीक वैसे ही जैसे आप यूनिक्स में होंगे।
राउल सालिनास-मोंटेगुडो

5

यहां मैंने एक फ़ंक्शन लिखा है जो यूनिक्स 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


सवाल था "पॉवरशेल में एक कमांड के निष्पादन का समय"। यूनिक्स का उपयोग करते हुए प्रक्रिया के समय के साथ क्या करना है?
जीन-क्लाउड DeMars

5
यह एक पॉवर्सशेल फ़ंक्शन है जिसे मैंने लिखा है, जो दिखाता है कि निष्पादन समय की गणना करने के लिए खुद का उपयोग करें Measure-Commandया विभिन्न अन्य तरीकों में से एक है जिसका आप पॉवर्सशेल में निष्पादन कर सकते हैं। यदि आप मूल प्रश्न को पढ़ते हैं, तो उसने " timeलिनक्स में कमांड की तरह" काम करने वाली चीज़ मांगी ।
सबसे महान

3

स्टॉपवॉच और स्वरूपित समय का उपयोग करना:

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 }

-2

उत्तर में निर्दिष्ट किसी भी प्रदर्शन माप आदेश से ड्राइंग (गलत) निष्कर्ष पर एक शब्द। कई प्रकार के नुकसान हैं जिन्हें एक कस्टम (कस्टम) फ़ंक्शन या कमांड के नंगे आह्वान समय को देखने से अलग रखा जाना चाहिए।

Sjoemelsoftware

'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) मुझे लगता है कि दो अवधारणाओं के बीच एक मामूली अंतर है क्योंकि आलसी मूल्यांकन के साथ परिणाम की गणना तब की जाती है जब इसे एप्लाय किया जाता है। आस्थगित निष्पादन थे परिणाम की गणना तब की जाती है जब सिस्टम निष्क्रिय होता है


इस उत्तर का उद्देश्य लोगों को PowerShell में टाइमिंग कमांड के संबंध में एक सामान्य गलतफहमी के लिए एक सामान्य प्रश्न के लिए संदर्भित करने में सक्षम होना है , जैसा कि मैंने अभी एक दोहराए जाने वाले प्रश्न के लिए किया है: पॉवर्सशेल प्रश्न - 500 मिलियन ऑब्जेक्ट्स के माध्यम से लूप के लिए सबसे तेज़ विधि की तलाश एक और 500k ऑब्जेक्ट ऐरे में मैच की तलाश में
iRon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.