param(
[Alias('Input')]
[string]
$InputPath = "$psScriptRoot/TestMarkdown",
[string]
$OutputPath = "$psScriptRoot/PowerShellFast"
)
$mdPipelineBuilder = [Markdig.MarkdownPipelineBuilder]::new()
$mdPipeline = [Markdig.MarkdownExtensions]::UsePipeTables($mdPipelineBuilder).Build()
foreach ($fullPath in [IO.Directory]::EnumerateFileSystemEntries($InputPath)) {
$fileHtml = [Markdig.Markdown]::ToHtml(
[IO.File]::ReadAllText($fullPath), $mdPipeline
)
$fileName = @($fullPath -split '[\\/]')[-1]
$directoryPath = $OutputPath, ($fileName -replace '\.md$') -join '/'
if (-not [IO.Directory]::Exists($directoryPath)) {
$null = [IO.Directory]::CreateDirectory($directoryPath)
}
$fileOutputPath = $OutputPath, ($fileName -replace '\.md$'), 'index.html' -join '/'
[IO.File]::WriteAllText($fileOutputPath, $fileHtml)
}
param(
[Alias('Input')]
[string]
$InputPath = "$psScriptRoot/TestMarkdown",
[string]
$OutputPath = "$psScriptRoot/PowerShellSlowest"
)
foreach ($file in Get-ChildItem -Path $InputPath -File) {
$fileHtml = (ConvertFrom-Markdown -LiteralPath $file.FullName).Html
$fileName = $file.Name
$fileOutputPath =
Join-Path $OutputPath ($fileName -replace '\.md$') |
Join-Path -ChildPath ('index.html')
New-Item -ItemType File -Path $fileOutputPath -Value $fileHtml -Force
}
param(
[Alias('Input')]
[string]
$InputPath = "$psScriptRoot/TestMarkdown",
[string]
$OutputPath = "$psScriptRoot/PowerShellConvertFromMarkdown"
)
foreach ($file in Get-ChildItem -Path $InputPath -File) {
$fileHtml = (ConvertFrom-Markdown -LiteralPath $file.FullName).Html
$fileName = $file.Name
$directoryPath = $OutputPath, ($fileName -replace '\.md$') -join '/'
if (-not [IO.Directory]::Exists($directoryPath)) {
$null = [IO.Directory]::CreateDirectory($directoryPath)
}
$fileOutputPath = $OutputPath, ($fileName -replace '\.md$'), 'index.html' -join '/'
[IO.File]::WriteAllText($fileOutputPath, $fileHtml)
}
param(
[Alias('Input')]
[string]
$InputPath = "$psScriptRoot/TestMarkdown",
[string]
$OutputPath = "$psScriptRoot/PowerShellForeachObject"
)
Get-ChildItem -Path $InputPath -File |
Foreach-Object {
$in = $_
New-Item -ItemType File -Path (
Join-Path $OutputPath ($in.Name -replace '\.md$') |
Join-Path -ChildPath ./index.html
) -Value (
($in |
ConvertFrom-Markdown |
Select-Object -ExpandProperty html)
) -Force
}
<#
.SYNOPSIS
Builds 4kb markdown files with 11ty
.DESCRIPTION
Builds 4kb markdown files with 11ty.
#>
Push-Location $PSScriptRoot
npx @11ty/eleventy --input=./TestMarkdown/*.md --output ./11ty/
Pop-Location
param(
[Alias('Input')]
[string]
$InputPath = "$psScriptRoot/TestMarkdown",
[string]
$OutputPath = "$psScriptRoot/PowerShellMarkX"
)
foreach ($fullPath in [IO.Directory]::EnumerateFileSystemEntries($InputPath)) {
$markx = markx ([IO.File]::ReadAllText($fullPath))
$fileName = @($fullPath -split '[\\/]')[-1]
$directoryPath = $OutputPath, ($fileName -replace '\.md$') -join '/'
if (-not [IO.Directory]::Exists($directoryPath)) {
$null = [IO.Directory]::CreateDirectory($directoryPath)
}
$fileOutputPath = $OutputPath, ($fileName -replace '\.md$'), 'index.html' -join '/'
[IO.File]::WriteAllText($fileOutputPath, $markx.html)
}
| Technique | Time | RelativeSpeed |
|---|---|---|
| build.with.powershell.fast | 00:00:01.0869980 | 0.08033470203371848 |
| build.with.powershell.New-Item | 00:00:02.7780891 | 0.20531496844669553 |
| build.with.powershell.ConvertFrom-Markdown | 00:00:02.8319524 | 0.2092957413239711 |
| build.with.powershell.Foreach-Object | 00:00:03.1304038 | 0.2313528235730149 |
| build.with.11ty | 00:00:07.9698237 | 0.5890106625778223 |
| build.with.powershell.markx | 00:00:13.5308649 | 1 |
<#
.SYNOPSIS
Builds 4kb Markdown files
.DESCRIPTION
Builds 4kb Markdown files N different ways, in order to test performance.
.NOTES
In the interests of fair play, any prerequisities should be installed before builds are timed.
#>
param()
Push-Location $PSScriptRoot
#region Install Prereqs
if ($env:GITHUB_WORKFLOW) {
$null = sudo npm install -g '@11ty/eleventy'
Install-Module MarkX -Force
Import-Module MarkX -Global
}
#endregion Install Prereqs
#region Get Clock Speed
$cpuSpeed =
if ($executionContext.SessionState.PSVariable.Get('IsLinux').Value) {
Get-Content /proc/cpuinfo -Raw -ErrorAction SilentlyContinue |
Select-String "(?<Unit>Mhz|MIPS)\s+\:\s+(?<Value>[\d\.]+)" |
Select-Object -First 1 -ExpandProperty Matches |
ForEach-Object {
$_.Groups["Value"].Value -as [int]
}
} elseif ($executionContext.SessionState.PSVariable.Get('IsMacOS').Value) {
(sysctl -n hw.cpufrequency) / 1e6 -as [int]
} else {
$getCimInstance = $ExecutionContext.SessionState.InvokeCommand.GetCommand('Get-CimInstance','Cmdlet')
if ($getCimInstance) {
& $getCimInstance -Class Win32_Processor |
Select-Object -ExpandProperty MaxClockSpeed
}
}
#endregion
$mySelf = $MyInvocation.MyCommand.ScriptBlock
& {
foreach ($file in Get-ChildItem -filter build.with.*.ps1) {
$techniqueName = $file.Name -replace '\.build\.with' -replace '\.ps1$'
$script = (Get-Command $file.FullName -CommandType ExternalScript).ScriptBlock
$time = Measure-Command { . $file.FullName }
[PSCustomObject]@{
Technique = $techniqueName
Time = $time
Script = $script
}
}
} | Tee-Object -Variable buildTimes
$buildTimes = $buildTimes | Sort-Object Time
foreach ($buildTime in $buildTimes) {
$relativeSpeed = $buildTime.Time.TotalMilliseconds / $buildTimes[-1].Time.TotalMilliseconds
Add-Member NoteProperty -InputObject $buildTime -Name RelativeSpeed $relativeSpeed -Force
}
$buildTimes | ConvertTo-Html -Title BuildTimes > ./times.html
@(
"<html>"
"<head>"
"<title>4kb Markdown Files</title>"
"<meta name='viewport' content='width=device-width, initial-scale=1, minimum-scale=1.0' />"
"<style>"
"
body { height: 100vh; max-width: 100vw; margin:0 }
svg { height: 5%; }
h1,h2, h3,h4 { text-align: center; }
.techniqueSummary { font-size: 2rem; }
"
"</style>"
"</head>"
"<body>"
"<h1>4kb Markdown Files Benchmark</h1>"
"<h2>Time to build 4096 markdown files</h2>"
"<h3>Last built at $([DateTime]::UtcNow.ToString("s")) running @ $cpuSpeed Mhz</h3>"
"<h4><a href='https://github.com/PowerShellWeb/4kbMarkdownFiles/'><button>Github Repo</button></a></h4>"
foreach ($buildTime in $buildTimes) {
"<details open>"
"<summary class='techniqueSummary'>$($buildTime.Technique) ($([Math]::Round(
$buildTime.Time.TotalSeconds, 2
))s)</summary>"
"<details>"
"<summary>Build Script</summary>"
"<pre><code class='langauge-PowerShell'>"
[Web.HttpUtility]::HtmlEncode($buildTime.Script)
"</code></pre>"
"</details>"
"<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'>"
"<rect x='0%' width='1%' height='100%'>"
"<animate attributeName='width' from='1%' to='$([Math]::Round($buildTime.relativeSpeed * 100, 2))%' dur='$($buildTime.Time.TotalSeconds)s' fill='freeze' />"
"</rect>"
"</svg>"
"</details>"
}
"<h3>The Numbers</h3>"
$buildTimes |
Select-Object Technique, Time, RelativeSpeed |
ConvertTo-Html -Fragment
"<details>"
"<summary>View Source</summary>"
"<pre><code class='language-PowerShell'>"
[Web.HttpUtility]::HtmlEncode("$mySelf")
"</code></pre>"
"</details>"
"</body>"
"</html>"
) > ./index.html
Pop-Location