2011-11-11 75 views
8

早些時候我正在閱讀SO上的answer,我想知道爲什麼它還沒有在PowerShell中被模擬過。在PowerShell中的Unix時間命令的等價物?

在unix/linux中,我們可以使用time命令作爲簡單的基準測試工具。

$ time ./script1.sh 

real 0m1.005s 
user 0m0.000s 
sys  0m0.008s 

在PowerShell中,我們可以使用measure-command類似:

$ Measure-Command {java post_incr} 

Days    : 0 
Hours    : 0 
Minutes   : 0 
Seconds   : 1 
Milliseconds  : 18 
Ticks    : 10188003 
TotalDays   : 1.17916701388889E-05 
TotalHours  : 0.000283000083333333 
TotalMinutes  : 0.016980005 
TotalSeconds  : 1.0188003 
TotalMilliseconds : 1018.8003 

但是,這是不一樣的time,該報告真實,用戶和SYS(見三者之間的區別鏈接的SO Answer)

這個(time)顯然是這樣一個有用的小工具。是否有任何用戶爲此功能編寫了cmdlet,還是已經在V3中或計劃用於將來的版本?

回答

2

使用GetProcessTimes函數編寫C程序,您可以在其中找到它的文檔:http://msdn.microsoft.com/en-us/library/ms683223%28VS.85%29.aspx

在本書「Windows系統編程」的例子中,有一個程序使用該函數來準確檢索您需要的內容(經過時間,內核時間,用戶時間)。該程序稱爲「timep.exe」,它可以在壓縮示例存檔內的runX子目錄(X來自編譯中使用的Visual Studio版本)中找到。這裏是您可以下載該檔案的作者頁面http://www.jmhartsoftware.com/,當然源代碼也在那裏,所以你可以看到timep.exe的工作原理。

1

我既用來來爲time的實現,System.Diagnostics.ProcessGetProcessTimes提供的時間:

[email protected]' 

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 

public class Timer 
    { 
     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern bool GetProcessTimes(IntPtr handle, out long creation, out long exit, out long kernel, 
                out long user); 

     public static void Time(string file,string args) 
     { 
      long user,kernel,exit,creation; 
      Process proc = null; 
      proc = Process.Start(file,args); 
      proc.WaitForExit(); 
      GetProcessTimes(proc.Handle, out creation, out exit, out kernel, out user); 
      long real = exit - creation; 
      Console.WriteLine("real {0}\nuser {1}\nsys {2}", real/10000000.0, user/10000000.0,kernel/10000000.0); 
     } 
    } 
'@ 

Add-Type -TypeDefinition $source -Language CSharpVersion3 

function time ($scriptblock) { 

    $file = "powershell"; 
    $args = $scriptblock; 

    $startInfo = new-object Diagnostics.ProcessStartInfo; 
    $startInfo.FileName = $file; 
    $startInfo.Arguments = $args; 
    $startInfo.CreateNoWindow = $true; 
    $startInfo.UseShellExecute = $false; 
    $startInfo.RedirectStandardOutput = $true; 
    $process = [Diagnostics.Process]::Start($startInfo); 
    $process.WaitForExit(); 
    write-host $process.StandardOutput.ReadToEnd(); 
    write-host real: ($process.ExitTime - $process.StartTime) 
    write-host user: $process.UserProcessorTime; 
    write-host sys: $process.PrivilegedProcessorTime; 
    write-host using GetProcessTimes 
    [Timer]::Time($file,$args) 
} 

time {sleep 10} 

這是不是真的完美的實時出來的11秒左右(爲sleep 10)因爲我正在創建一個PowerShell進程並在其中運行該命令。我會看看我是否可以實現一個cmdlet或其他東西。

+1

我真的很習慣使用Windows Powershell,你能解釋一下我需要做什麼來使用你的'時間'執行嗎? – Amndeep7

0

您嘗試測量的過程也可能會在後臺分支並運行,導致測量結果縮短。您可以使用啓動過程-Wait參數來獲得您期望的全時測量。下面是一個例子,顯示它需要關閉一個空閒連接34秒鐘:

$program = 'telnet' 
$ArgumentList = 'stackoverflow.com 80' 
$WorkingDirectory = 'c:\' 
Measure-Command { 
    $p = Start-Process -FilePath $program -ArgumentList $ArgumentList -Wait -PassThru -WorkingDirectory $WorkingDirectory -NoNewWindow; 
    Write-Host $p.ExitCode; 
} 


#Output: 
0 


Days    : 0 
Hours    : 0 
Minutes   : 0 
Seconds   : 34 
Milliseconds  : 37 
Ticks    : 340370635 
TotalDays   : 0.000393947494212963 
TotalHours  : 0.00945473986111111 
TotalMinutes  : 0.567284391666667 
TotalSeconds  : 34.0370635 
TotalMilliseconds : 34037.0635 
1

警告,PowerShell提前。

一些咖啡幫我想出了這一點:

function time { $Command = "$args"; Measure-Command { Invoke-Expression $Command 2>&1 | out-default} } 

如果你想讓它輸出什麼,只是用了空替換:

function timequiet { $Command = "$args"; Measure-Command { Invoke-Expression $Command 2>&1 | out-null} } 

你使用這樣的:

PS C:\> time sleep 5 


Days    : 0 
Hours    : 0 
Minutes   : 0 
Seconds   : 4 
Milliseconds  : 990 
Ticks    : 49906722 
TotalDays   : 5,77624097222222E-05 
TotalHours  : 0,00138629783333333 
TotalMinutes  : 0,08317787 
TotalSeconds  : 4,9906722 
TotalMilliseconds : 4990,6722 



PS C:\> 
相關問題