Merge pull request #3 from KevinMarquette/develop !deploy
Created a processing to smooth out some artifacts, added line number support and updated readme.
This commit is contained in:
@@ -3,18 +3,26 @@ class Chronometer
|
||||
[hashtable]$FileMap = @{}
|
||||
$Breakpoint = @()
|
||||
|
||||
[void]AddBreakpoint([string[]]$Path)
|
||||
[void]AddBreakpoint([string[]]$Path, [int[]]$LineNumber)
|
||||
{
|
||||
foreach($file in (Resolve-Path $Path -ea 0))
|
||||
{
|
||||
$script = [MonitoredScript]@{Path=$file.Path}
|
||||
$lines = $script.SetScript($file)
|
||||
if($LineNumber -ne $null)
|
||||
{
|
||||
$bpLine = $LineNumber
|
||||
}
|
||||
else
|
||||
{
|
||||
$bpLine = (1..$lines)
|
||||
}
|
||||
|
||||
$this.fileMap[$file.Path] = $script
|
||||
|
||||
$breakpointParam = @{
|
||||
Script = $file
|
||||
Line = (1..$lines)
|
||||
Line = $bpLine
|
||||
Action = {[ScriptProfiler]::RecordExecution( $_) }
|
||||
}
|
||||
$this.breakPoint += Set-PSBreakpoint @breakpointParam
|
||||
@@ -42,6 +50,10 @@ class Chronometer
|
||||
|
||||
[MonitoredScript[]] GetResults()
|
||||
{
|
||||
foreach($node in $this.FileMap.Values)
|
||||
{
|
||||
$node.PostProcessing()
|
||||
}
|
||||
return $this.FileMap.Values
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,4 +46,36 @@ class MonitoredScript
|
||||
$this.lastRecord = $record
|
||||
$this.lastNode = $node
|
||||
}
|
||||
|
||||
[void] PostProcessing()
|
||||
{
|
||||
$this.lastNode = $null
|
||||
$this.ExecutionTime = 0
|
||||
foreach($node in $this.line)
|
||||
{
|
||||
$command = $node.text -replace '\s',''
|
||||
|
||||
switch -Regex ($command)
|
||||
{
|
||||
'^}$|^}#|^$' {
|
||||
if($node.HitCount -eq 0)
|
||||
{
|
||||
$node.HitCount = $this.lastNode.HitCount
|
||||
}
|
||||
$node.Milliseconds = 0
|
||||
$node.Average = 0
|
||||
$this.lastNode = $node
|
||||
}
|
||||
'^{$|^{#}' {
|
||||
$node.Milliseconds = 0
|
||||
$node.Average = 0
|
||||
$this.lastNode = $node
|
||||
}
|
||||
default {
|
||||
$this.lastNode = $node
|
||||
}
|
||||
}
|
||||
$this.ExecutionTime += $node.Milliseconds
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,10 @@ function Get-Chronometer
|
||||
[string[]]
|
||||
$Path,
|
||||
|
||||
# Line numbers within the script file to measure
|
||||
[int[]]
|
||||
$LineNumber = $null,
|
||||
|
||||
# The script to start the scrupt or execute other commands
|
||||
[alias('Script','CommandScript')]
|
||||
[scriptblock]
|
||||
@@ -24,7 +28,7 @@ function Get-Chronometer
|
||||
$Chronometer = [Chronometer]::New()
|
||||
|
||||
Write-Verbose "Setting breapoints"
|
||||
$Chronometer.AddBreakpoint($Path)
|
||||
$Chronometer.AddBreakpoint($Path,$LineNumber)
|
||||
|
||||
if($Chronometer.breakPoint -ne $null)
|
||||
{
|
||||
|
||||
19
README.md
19
README.md
@@ -2,24 +2,35 @@
|
||||
A module for measuring performance of Powershell scripts, one line at a time
|
||||
|
||||
## Project status
|
||||
Experimental. Just a working idea at the moment. Functions and argument names are still up in the air. Also don't consider it stable or tested. Use at your own risk.
|
||||
Preview release. The core logic is fleshed out but more testing is needed.
|
||||
|
||||
# Getting started
|
||||
## Prerequirements
|
||||
You need to have Powershell 5.0 or newer. This module uses classes.
|
||||
|
||||
## Installing Chronometer
|
||||
Place the Chronometer folder into your `$PSModulePath`. I will publish to the Powershell Gallery once the project is more stable.
|
||||
This is published in the Powershell Gallery
|
||||
|
||||
Install-Module Chronometer
|
||||
|
||||
## Basic usage
|
||||
Provide a script file and a command to execute.
|
||||
|
||||
$path = myscript.ps1
|
||||
$Chronometer = Get-Chronometer -Path $path -Script {. .\myscript.ps1}
|
||||
$Chronometer | % tostring | Format-Chronometer
|
||||
$Chronometer | Format-Chronometer
|
||||
|
||||
The user experience is important to me but I am working on the core logic right now. I will loop back to make it more intuitive and simple to use.
|
||||
|
||||
## Things to know
|
||||
The `Path` can be any ps1 and the script can run any command. Ideally, you would either execute the script or load the script and execute a command inside it.
|
||||
|
||||
Here is a more complex example:
|
||||
|
||||
$script = ls C:\workspace\PSGraph\PSGraph -Recurse -Filter *.ps1
|
||||
$Chronometer = @{
|
||||
Path = $script.fullname
|
||||
Script = {Invoke-Pester C:\workspace\PSGraph}
|
||||
}
|
||||
$results = Get-Chronometer @Chronometer
|
||||
$results | Format-Chronometer
|
||||
|
||||
|
||||
@@ -17,6 +17,17 @@ Describe "Basic unit tests" -Tags Build {
|
||||
$results = Get-Chronometer -Path $PSScriptRoot\..\ScratchFiles\example.ps1 -Script {. "$PSScriptRoot\..\ScratchFiles\example.ps1"}
|
||||
$results | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
it "Executes a script with linenumbers and gives results" {
|
||||
# Get-Chronometer -Path ScratchFiles\example.ps1 -Script {"Test"}
|
||||
$params = @{
|
||||
Path = "$PSScriptRoot\..\ScratchFiles\example.ps1"
|
||||
Script = {. "$PSScriptRoot\..\ScratchFiles\example.ps1"}
|
||||
LineNumber = 2,3,5,6
|
||||
}
|
||||
$results = Get-Chronometer @params
|
||||
$results | Should Not BeNullOrEmpty
|
||||
}
|
||||
}
|
||||
|
||||
Context "Function: Format-Chronometer" {
|
||||
|
||||
Reference in New Issue
Block a user