Created
January 26, 2023 19:31
-
-
Save jhochwald/55e1b4454232b0435ebec05d5f2d0d58 to your computer and use it in GitHub Desktop.
File I/O Speed-Testing - compare native .NET vs. native Powershell (Just an example)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -Version 3.0 | |
<# | |
.SYNOPSIS | |
File I/O Speed-Testing | |
.DESCRIPTION | |
File I/O Speed-Testing | |
.PARAMETER ReadFile | |
File to Read (must exist) | |
.PARAMETER WriteTarget | |
File to Write | |
.PARAMETER Number | |
Number of times, the inputfile is multiplied (to simmulate more, bigger, I/O) | |
.PARAMETER InputFile | |
File to read for the test (MUST EXIST) | |
.PARAMETER TestRun | |
Time to run the test | |
Default is:2 | |
Min: 1 | |
Max: 5 | |
.EXAMPLE | |
PS C:\> .\FileSpeedTest.ps1 | |
.NOTES | |
Basic example for some I/O tests | |
We decided to use a smaller input-file and multiply the content to generate a bigger one. In our test-case, the input-file hat about 500KB. | |
You can use a bigger one, and decrease the multiplication (-Number). | |
You can also increase the number of tests (-TestRun), but then you should reduce the output or save it into a log (can get long) | |
#> | |
[CmdletBinding(ConfirmImpact = 'None')] | |
[OutputType([string])] | |
param | |
( | |
[Parameter(ValueFromPipeline, | |
ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$ReadFile = 'c:\temp\test_large.txt', | |
[Parameter(ValueFromPipeline, | |
ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$WriteTarget = 'c:\temp\test.txt', | |
[Parameter(ValueFromPipeline, | |
ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[int] | |
$Number = 100, | |
[Parameter(ValueFromPipeline, | |
ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$InputFile = 'C:\DEV\Temp\Product names and service plan identifiers for licensing_raw.csv', | |
[Parameter(ValueFromPipeline, | |
ValueFromPipelineByPropertyName)] | |
[ValidateRange(1, 5)] | |
[ValidateNotNullOrEmpty()] | |
[int] | |
$TestRun = 2 | |
) | |
begin | |
{ | |
Clear-Host | |
Write-Verbose -Message ('Prepare file ({0} time the input)' -f $Number) | |
#region GenerateTestData | |
$DNETDATA = ([IO.File]::ReadAllLines($InputFile)) | |
$WriteData = (1 .. $Number | ForEach-Object -Process { | |
$DNETDATA | |
}) | |
$null = ([IO.file]::WriteAllText($ReadFile, $WriteData)) | |
#endregion GenerateTestData | |
#region Functions | |
function Format-FileSize | |
{ | |
[CmdletBinding(ConfirmImpact = 'None')] | |
[OutputType([string])] | |
param | |
( | |
[Parameter(Mandatory, HelpMessage = 'File-Size to tranform/format', | |
ValueFromPipeline, | |
ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[int] | |
$size | |
) | |
process | |
{ | |
switch ($size) | |
{ | |
{ | |
$_ -gt 1TB | |
} | |
{ | |
[string]::Format('{0:0.00} TB', $size / 1TB) | |
} | |
{ | |
$_ -gt 1GB | |
} | |
{ | |
[string]::Format('{0:0.00} GB', $size / 1GB) | |
} | |
{ | |
$_ -gt 1MB | |
} | |
{ | |
[string]::Format('{0:0.00} MB', $size / 1MB) | |
} | |
{ | |
$_ -gt 1KB | |
} | |
{ | |
[string]::Format('{0:0.00} kB', $size / 1KB) | |
} | |
{ | |
$_ -gt 0 | |
} | |
{ | |
[string]::Format('{0:0.00} B', $size) | |
} | |
Default | |
{ | |
'Unknown size' | |
break | |
} | |
} | |
} | |
} | |
#endregion Functions | |
('The Test-File size is: {0}' -f $(Format-FileSize -size ((Get-Item -Path $ReadFile).length))) | |
' ' | |
$DNETDATA = $null | |
'---------------------------------------------------------------------------------' | |
#region ScriptBlock | |
$ScriptBlock = { | |
' ' | |
('-> READCOUNT: {0}' -f $_) | |
' ' | |
'Read - PowerShell:' | |
([int](Measure-Command -Expression { | |
$null = (Get-Content -Path $ReadFile) | |
}).TotalMilliseconds) | |
' ' | |
'Read - .NET System.IO (ReadAllLines):' | |
([int](Measure-Command -Expression { | |
$null = ([IO.File]::ReadAllLines($ReadFile)) | |
}).TotalMilliseconds) | |
' ' | |
'Read - .NET System.IO (ReadAllText):' | |
([int](Measure-Command -Expression { | |
$null = ([IO.File]::ReadAllText($ReadFile)) | |
}).TotalMilliseconds) | |
' ' | |
('-> WRITECOUNT: {0}' -f $_) | |
$null = (Remove-Item -Path $WriteTarget -Force -ErrorAction SilentlyContinue) | |
' ' | |
'Write - PowerShell (Set-Content):' | |
([int](Measure-Command -Expression { | |
$null = ($WriteData | Set-Content -Path $WriteTarget -Force) | |
}).TotalMilliseconds) | |
$null = (Remove-Item -Path $WriteTarget -Force -ErrorAction SilentlyContinue) | |
' ' | |
'Write - PowerShell (Out-File):' | |
([int](Measure-Command -Expression { | |
$null = ($WriteData | Out-File -FilePath $WriteTarget -Force) | |
}).TotalMilliseconds) | |
$null = (Remove-Item -Path $WriteTarget -Force -ErrorAction SilentlyContinue) | |
' ' | |
'Read - .NET System.IO (WriteAllText):' | |
([int](Measure-Command -Expression { | |
$null = ([IO.file]::WriteAllText($WriteTarget, $WriteData)) | |
}).TotalMilliseconds) | |
$null = (Remove-Item -Path $WriteTarget -Force -ErrorAction SilentlyContinue) | |
' ' | |
'Read - .NET System.IO (AppendAllText):' | |
([int](Measure-Command -Expression { | |
$null = ([IO.file]::AppendAllText($WriteTarget, $WriteData)) | |
}).TotalMilliseconds) | |
$null = (Remove-Item -Path $WriteTarget -Force -ErrorAction SilentlyContinue) | |
' ' | |
'---------------------------------------------------------------------------------' | |
} | |
#endregion ScriptBlock | |
} | |
process | |
{ | |
1 .. $TestRun | ForEach-Object -Process { | |
(Invoke-Command -ScriptBlock $ScriptBlock) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is just an example! You need to use a valid input (text) file. You can multiply the input and run the tests as often as you like. Re-Run (e.g., run it multiple times) can prevent any warmup or caching events.
Do not run (-TestRun) the tests within one loop. You need to scroll (a lot) to gather all the information. On the other hand, you can pipe everything into a log!
The file is just a showcase, nothing more nothing less!