2011-11-11 65 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:\> 
相关问题