Эквивалент времени команды Unix в PowerShell? - PullRequest
11 голосов
/ 11 ноября 2011

Раньше я читал отличный ответ на SO и удивлялся, почему он еще не эмулировался в PowerShell.

В 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, который сообщает real, user и sys (см. Разницу между тремя в связанном SO-ответе.)

Это (time), очевидно, такой полезный маленький инструмент. Существуют ли какие-либо пользовательские командлеты для этой функции или они уже включены в V3 или запланированы на будущие выпуски?

Ответы [ 4 ]

3 голосов
/ 29 января 2018

Предупреждение, PowerShell впереди.

Кофе помог мне придумать следующее:

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

И если вы хотите, чтобы он ничего не выводил, просто замените на out-null:

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:\>
2 голосов
/ 12 ноября 2011

Напишите программу на C, используя функцию GetProcessTimes, вы можете найти ее документацию в: 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 голос
/ 31 декабря 2015

Процесс, который вы пытаетесь измерить, также может быть запущен в фоновом режиме, что приводит к прерыванию измерения Measure-Command .Вы можете использовать Start-Process с параметром -Wait , чтобы получить ожидаемое измерение полного времени.Вот пример, который показывает, что stackoverflow.com требуется 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 голос
/ 13 ноября 2011

Я использовал оба значения, предоставленные System.Diagnostics.Process и GetProcessTimes, чтобы придумать реализацию для time:

$source=@'

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 и запускаю команду в нем.Я посмотрю, смогу ли я реализовать командлет или что-то для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...