qem 0.7.0

High-performance cross-platform text engine for massive files.
Documentation
param(
    [string]$InputJsonl = "target\perf-matrix.jsonl",
    [string]$OutputMarkdown = "target\perf-matrix-summary.md"
)

$ErrorActionPreference = "Stop"
$InvariantCulture = [System.Globalization.CultureInfo]::InvariantCulture

function Format-InvariantNumber {
    param(
        [double]$Value
    )

    return $Value.ToString("0.000", $InvariantCulture)
}

function Format-SizeLabel {
    param(
        [double]$Bytes
    )

    if ($Bytes -ge 1GB) {
        return ('{0} GiB' -f (Format-InvariantNumber ($Bytes / 1GB)))
    }
    if ($Bytes -ge 1MB) {
        return ('{0} MiB' -f (Format-InvariantNumber ($Bytes / 1MB)))
    }
    if ($Bytes -ge 1KB) {
        return ('{0} KiB' -f (Format-InvariantNumber ($Bytes / 1KB)))
    }

    return ('{0} B' -f [int64]$Bytes)
}

function Get-StatsRow {
    param(
        [object[]]$Values
    )

    $filtered = @($Values | Where-Object { $_ -ne $null })
    if ($filtered.Count -eq 0) {
        return @{
            median = "-"
            min = "-"
            max = "-"
        }
    }

    $sorted = @($filtered | Sort-Object)
    $count = $sorted.Count
    if ($count % 2 -eq 1) {
        $median = [double]$sorted[[int]($count / 2)]
    }
    else {
        $median = ([double]$sorted[($count / 2) - 1] + [double]$sorted[$count / 2]) / 2.0
    }

    return @{
        median = (Format-InvariantNumber ([double]$median))
        min = (Format-InvariantNumber ([double]$sorted[0]))
        max = (Format-InvariantNumber ([double]$sorted[$count - 1]))
    }
}

$repoRoot = Split-Path -Parent $PSScriptRoot
$inputPath = Join-Path $repoRoot $InputJsonl
$outputPath = Join-Path $repoRoot $OutputMarkdown

if (-not (Test-Path $inputPath)) {
    throw "Input JSONL not found: $inputPath"
}

$rows = Get-Content $inputPath |
    Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
    ForEach-Object { $_ | ConvertFrom-Json }

if ($rows.Count -eq 0) {
    throw "Input JSONL is empty: $inputPath"
}

$groups = $rows | Group-Object {
    "{0}|{1}|{2}|{3}|{4}" -f $_.matrix_input_label, $_.matrix_state, $_.backing, $_.matrix_label, $_.matrix_viewport_anchor
}

$lines = New-Object System.Collections.Generic.List[string]
$lines.Add("# Perf Matrix Summary")
$lines.Add("")
$lines.Add(('Source: `{0}`' -f $InputJsonl))
$lines.Add("")
$lines.Add('| input | size | label | anchor | state | backing | runs | open ms | index wait ms | exact line wait ms | edit ms | viewport ms | save ms | next ms | prev ms | find_all ms | peak WS MiB |')
$lines.Add('| --- | --- | --- | --- | --- | --- | ---: | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---: |')

foreach ($group in ($groups | Sort-Object Name)) {
    $parts = $group.Name.Split('|', 5)
    $inputLabel = $parts[0]
    $state = $parts[1]
    $backing = $parts[2]
    $matrixLabel = $parts[3]
    $viewportAnchor = $parts[4]
    if ([string]::IsNullOrWhiteSpace($matrixLabel)) {
        $matrixLabel = "-"
    }
    if ([string]::IsNullOrWhiteSpace($viewportAnchor)) {
        $viewportAnchor = "middle"
    }

    $firstRow = $group.Group | Select-Object -First 1
    $sizeLabel = Format-SizeLabel ([double]$firstRow.file_len_bytes)

    $openStats = Get-StatsRow ($group.Group | ForEach-Object { $_.open_ms })
    $indexWaitStats = Get-StatsRow ($group.Group | ForEach-Object { $_.index_wait_ms })
    $exactLineWaitStats = Get-StatsRow ($group.Group | ForEach-Object { $_.exact_line_count_wait_ms })
    $seedEditStats = Get-StatsRow ($group.Group | ForEach-Object { $_.seed_edit_ms })
    $viewportStats = Get-StatsRow ($group.Group | ForEach-Object { $_.viewport_ms })
    $saveStats = Get-StatsRow ($group.Group | ForEach-Object { $_.save_ms })
    $nextStats = Get-StatsRow ($group.Group | ForEach-Object { $_.next_ms })
    $prevStats = Get-StatsRow ($group.Group | ForEach-Object { $_.prev_ms })
    $findAllStats = Get-StatsRow ($group.Group | ForEach-Object { $_.find_all_ms })
    $peakWorkingSetStats = Get-StatsRow (
        $group.Group | ForEach-Object {
            if ($_.PSObject.Properties.Name -contains 'matrix_peak_working_set_bytes' -and $_.matrix_peak_working_set_bytes -ne $null) {
                ([double]$_.matrix_peak_working_set_bytes) / 1MB
            }
            else {
                $null
            }
        }
    )

    $row = @(
        $inputLabel,
        $sizeLabel,
        $matrixLabel,
        $viewportAnchor,
        $state,
        $backing,
        [string]$group.Count,
        ('{0} [{1}-{2}]' -f $openStats.median, $openStats.min, $openStats.max),
        ('{0} [{1}-{2}]' -f $indexWaitStats.median, $indexWaitStats.min, $indexWaitStats.max),
        ('{0} [{1}-{2}]' -f $exactLineWaitStats.median, $exactLineWaitStats.min, $exactLineWaitStats.max),
        ('{0} [{1}-{2}]' -f $seedEditStats.median, $seedEditStats.min, $seedEditStats.max),
        ('{0} [{1}-{2}]' -f $viewportStats.median, $viewportStats.min, $viewportStats.max),
        ('{0} [{1}-{2}]' -f $saveStats.median, $saveStats.min, $saveStats.max),
        ('{0} [{1}-{2}]' -f $nextStats.median, $nextStats.min, $nextStats.max),
        ('{0} [{1}-{2}]' -f $prevStats.median, $prevStats.min, $prevStats.max),
        ('{0} [{1}-{2}]' -f $findAllStats.median, $findAllStats.min, $findAllStats.max),
        ('{0} [{1}-{2}]' -f $peakWorkingSetStats.median, $peakWorkingSetStats.min, $peakWorkingSetStats.max)
    )
    $lines.Add('| ' + ($row -join ' | ') + ' |')
}

$outputDir = Split-Path -Parent $outputPath
if (-not (Test-Path $outputDir)) {
    New-Item -ItemType Directory -Path $outputDir | Out-Null
}

$lines | Set-Content -Path $outputPath
Write-Host ("Wrote markdown summary to {0}" -f $outputPath)