PoshCode Logo PowerShell Code Repository

Get-PerformanceHistory 2 (modification of post by Joel Bennett view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/683"></script>download | new post

This much more complicated version of Get-PerformanceHistory shows the approximate length of the command or script, as well as how long it took to run. Great for those “my script is shorter/faster/cooler” than yours bragging sessions on IRC ... or whatever. Lets you compare several commands by just running each of them and then calling Get-PerformanceHistory -Count 4

  1. ##requires -version 2.0
  2. ## Get-PerformanceHistory.ps1
  3. ##############################################################################################################
  4. ## Lets you see the amount of time recent commands in your history have taken
  5. ## History:
  6. ## v2.53 - added back the Lines, Words, and Characters ....
  7. ## v2.52 - added regex-based iteration counting to calculate averages
  8. ## v2.51 - removed PsParser features to make it v1 compatible
  9. ## v2.5 - added "average" calculation if the first thing in your command line is a range: 1..x
  10. ## v2   - added measuring the scripts involved in the command, (uses Tokenizer)
  11. ##      - adds a ton of parsing to make the output pretty
  12. ##############################################################################################################
  13. function Get-PerformanceHistory {
  14. param( [int]$count=1, [int[]]$id=@((Get-History -count 1| Select Id).Id) )
  15.  
  16. ## Removed to make this v1 compatible
  17. ## $Parser = [System.Management.Automation.PsParser]
  18. function FormatTimeSpan($ts) {
  19.    if($ts.Minutes) {
  20.       if($ts.Hours) {
  21.          if($ts.Days) {
  22.             return "{0:##}d {1:00}:{2:00}:{3:00}.{4:00000}" -f $ts.Days, $ts.Hours, $ts.Minutes, $ts.Seconds, [int](100000 * ($ts.TotalSeconds - [Math]::Floor($ts.TotalSeconds)))
  23.          }
  24.          return "{0:##}:{1:00}:{2:00}.{3:00000}" -f $ts.Hours, $ts.Minutes, $ts.Seconds, [int](100000 * ($ts.TotalSeconds - [Math]::Floor($ts.TotalSeconds)))
  25.       }
  26.       return "{0:##}:{1:00}.{2:00000}" -f $ts.Minutes, $ts.Seconds, [int](100000 * ($ts.TotalSeconds - [Math]::Floor($ts.TotalSeconds)))
  27.    }
  28.    return "{0:#0}.{1:00000}" -f $ts.Seconds, [int](100000 * ($ts.TotalSeconds - [Math]::Floor($ts.TotalSeconds)))
  29. }
  30.  
  31. # if there's only one id, then the count counts, otherwise we just use the ids
  32. # ... basically:    { 1..$count | % { $id += $id[-1]-1 }  }
  33. if($id.Count -eq 1) { $id = ($id[0])..($id[0]-($count-1)) }
  34.  
  35. # so we can call it with just the IDs
  36. Get-History -id $id |
  37. ForEach {
  38.    $msr = $null
  39.    $cmd = $_
  40.    # default formatting values
  41.    $avg = 7; $len = 8; $count = 1
  42.    
  43. ## Removed to make this v1 compatible
  44. ##   $tok = $Parser::Tokenize( $cmd.CommandLine, [ref]$null )
  45. ##   if( ($tok[0].Type -eq "Number") -and
  46. ##       ($tok[0].Content -le 1) -and
  47. ##       ($tok[2].Type -eq "Number") -and
  48. ##       ($tok[1].Content -eq "..") )
  49. ##   {
  50. ##      $count = ([int]$tok[2].Content) - ([int]$tok[0].Content) + 1
  51. ##   }
  52. ##  
  53. ##   $com = @( $tok | where {$_.Type -eq "Command"} |
  54. ##                     foreach {
  55. ##                        $Local:ErrorActionPreference = "SilentlyContinue"
  56. ##                        get-command $_.Content
  57. ##                        $Local:ErrorActionPreference = $Script:ErrorActionPreference
  58. ##                     } |
  59. ##                     where { $_.CommandType -eq "ExternalScript" } |
  60. ##                     foreach { $_.Path } )
  61. ##                    
  62. ##   # If we actually got a script, measure it out
  63. ##   if($com.Count -gt 0){
  64. ##      $msr = Get-Content -path $com | Measure-Object -Line -Word -Char
  65. ##   } else {
  66.       $msr = Measure-Object -in $cmd.CommandLine -Line -Word -Char
  67. ##   }
  68.  
  69. ## V1 Averages:
  70. $min, $max = ([regex]"^\s*(?:(?<min>\d+)\.\.(?<max>\d+)\s+\||for\s*\([^=]+=\s*(?<min>\d+)\s*;[^;]+\-lt\s*(?<max>\d+)\s*;[^;)]+\)\s*{)").match( $cmd.CommandLine ).Groups[1,2] | % { [int]$_.Value }
  71. $count = $max - $min
  72. if($count -le 0 ) { $count = 1 }
  73.    
  74.    "" | Select @{n="Id";        e={$cmd.Id}},
  75.                @{n="Duration";  e={FormatTimeSpan ($cmd.EndExecutionTime - $cmd.StartExecutionTime)}},
  76.                @{n="Average";   e={FormatTimeSpan ([TimeSpan]::FromTicks( (($cmd.EndExecutionTime - $cmd.StartExecutionTime).Ticks / $count) ))}},
  77.                @{n="Lines";     e={$msr.Lines}},
  78.                @{n="Words";     e={$msr.Words}},
  79.                @{n="Chars";     e={$msr.Characters}},
  80.                @{n="Type";      e={if($com.Count -gt 0){"Script"}else{"Command"}}},
  81.                @{n="Commmand";  e={$cmd.CommandLine}}
  82. } |
  83. # I have to figure out what the longest time string is to make it look its best
  84. Foreach {
  85. $avg = [Math]::Max($avg,$_.Average.Length);
  86. $len = [Math]::Max($len,$_.Duration.Length);  
  87. $_ } | Sort Id |
  88. Format-Table @{l="Duration";e={"{0,$len}" -f $_.Duration}},@{l="Average";e={"{0,$avg}" -f $_.Average}},Lines,Words,Chars,Type,Commmand -auto
  89. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me