Skip to content

Instantly share code, notes, and snippets.

@Krzysiu
Created March 11, 2026 00:47
Show Gist options
  • Select an option

  • Save Krzysiu/4a2ccc159ce19b44c53511cff634304d to your computer and use it in GitHub Desktop.

Select an option

Save Krzysiu/4a2ccc159ce19b44c53511cff634304d to your computer and use it in GitHub Desktop.
ChaiNNer benchmark - precise calculation of processing time
<#
.SYNOPSIS
chaiNNer benchmark script - precise performance measurement tool or how to overthink a simple script. 🥜🔨
Be sure to check config variables below!
.DESCRIPTION
This script correlates chaiNNer execution logs with file system metadata to provide
accurate image processing duration. it extracts engine parameters (pytorch, ncnn, onnx)
and detailed file info (mpix).
.LICENSE
MIT License (C) 2026 Krzysztof Blachnicki
.EXAMPLE OUTPUT (SHORT MODE)
10,049
.EXAMPLE OUTPUT (OVERKILL MODE)
Hardware Stats
CPU: Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz
Memory: 16 GB
Graphic card: NVIDIA GeForce GTX 1050 Ti
-------------------------
PyTorch: [GPU] [FP16: True] [Budget: 3GB]
NCNN: [GPU Index: 0] [Budget: 0GB]
ONNX: [Provider: CUDAExecutionProvider] [TRT-FP16: True]
-------------------------
Benchmark Results
Output file info: 689 x 689 (0.47 MPix)
Start: 01:06:04.829
End: 01:06:14.877
Total Duration: 10,049 seconds
-------------------------
.NOTES
- confirmed working with chaiNNer 0.25.1 (the most recent, as of march 2026).
- future versions may require regex updates if log string formats change.
- start time: last "running new executor" entry in main.log.
- end time: file modification timestamp (lastwritetime).
- tip: use "save file" node instead of "view file" (external app) for accurate results.
- simple mode: set $simpleMode to $true for "seconds only" output.
.SUPPORT ME :3
If you ever wanted to hug a real life bear 🧸, you are crazy enough to donate my overkill tools 🛠️
https://buymeacoffee.com/krzysiunet ☕
...and for those who like to explore given situation: https://krzysiu.net/up/files/krzys_i_mis.jpg 📸 🐻
#>
# --- CONFIG START ---
$FilePath = "" # leave empty for file picker; set a full path to automate.
$SimpleMode = $false # set to $true for "seconds only" output (skips hardware, engines and image info).
$LogPath = "$env:APPDATA\chaiNNer\logs\main.log" # default log location, don't change unless you already messed with defaults of ChaiNNer
# --- CONFIG END ---
if ([string]::IsNullOrWhiteSpace($FilePath)) {
Add-Type -AssemblyName System.Windows.Forms
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog
$FileBrowser.InitialDirectory = [System.IO.Path]::GetTempPath()
$FileBrowser.Filter = "Images (*.png;*.jpg;*.tiff;*.tif)|*.png;*.jpg;*.tiff;*.tif"
if ($FileBrowser.ShowDialog() -eq "OK") {
[string]$FilePath = $FileBrowser.FileName
} else { exit }
}
if (-not $SimpleMode) {
$cpu = Get-CimInstance Win32_Processor | Select-Object -First 1
$gpu = Get-CimInstance Win32_VideoController | Where-Object { $_.Name -notlike "*Basic*" } | Select-Object -First 1
$mem = Get-CimInstance Win32_ComputerSystem | Select-Object @{Name="TotalGB";Expression={[Math]::Round($_.TotalPhysicalMemory / 1GB)}}
Write-Host "`nHardware Stats" -ForegroundColor Yellow
Write-Host "CPU: $($cpu.Name)"
Write-Host "Memory: $($mem.TotalGB) GB"
Write-Host "Graphic card: $($gpu.Name)"
Write-Host "-------------------------"
}
if (Test-Path -LiteralPath $FilePath) {
$w = $h = $mpix = 0
if (-not $SimpleMode) {
Add-Type -AssemblyName PresentationCore
try {
$fileStream = New-Object System.IO.FileStream($FilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
$decoder = [System.Windows.Media.Imaging.BitmapDecoder]::Create($fileStream, "None", "Default")
$frame = $decoder.Frames[0]
$w = $frame.PixelWidth
$h = $h = $frame.PixelHeight
$mpix = [Math]::Round(($w * $h) / 1000000, 2)
$fileStream.Close(); $fileStream.Dispose()
} catch {
if($fileStream) { $fileStream.Close() }
}
}
$LogContent = Get-Content $LogPath -Raw
$Lines = $LogContent -split "`r?`n"
$ExecLine = $Lines | Select-String "Execution options:" | Select-Object -Last 1 | ForEach-Object { $_.ToString() }
$StartLine = $Lines | Select-String "Running new executor" | Select-Object -Last 1 | ForEach-Object { $_.ToString() }
if ($StartLine -match "\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\]") {
$Start = [DateTime]::ParseExact($Matches[1], "yyyy-MM-dd HH:mm:ss.fff", $null)
$End = (Get-Item -LiteralPath $FilePath).LastWriteTime
$Duration = ($End - $Start).TotalSeconds.ToString('N3')
if (-not $SimpleMode -and $ExecLine -match "Execution options: (\{.*\})") {
$Json = ($Matches[1] -replace "'", '"' -replace "True", "true" -replace "False", "false") | ConvertFrom-Json
Write-Host "PyTorch: [$(if($Json.chaiNNer_pytorch.use_cpu){"CPU"}else{"GPU"})] [FP16: $($Json.chaiNNer_pytorch.use_fp16)] [Budget: $($Json.chaiNNer_pytorch.budget_limit)GB]" -ForegroundColor Magenta
Write-Host "NCNN: [GPU Index: $($Json.chaiNNer_ncnn.gpu_index)] [Budget: $($Json.chaiNNer_ncnn.budget_limit)GB]" -ForegroundColor Magenta
Write-Host "ONNX: [Provider: $($Json.chaiNNer_onnx.execution_provider)] [TRT-FP16: $($Json.chaiNNer_onnx.tensorrt_fp16_mode)]" -ForegroundColor Magenta
Write-Host "-------------------------"
}
if ($SimpleMode) {
Write-Host $Duration
} else {
Write-Host "Benchmark Results" -ForegroundColor Cyan
Write-Host "Total Duration: $($Duration) seconds" -ForegroundColor Green
Write-Host "Output file info: $($w) x $($h) ($($mpix) MPix)"
Write-Host "Start: $($Start.ToString('HH:mm:ss.fff'))"
Write-Host "End: $($End.ToString('HH:mm:ss.fff'))"
Write-Host "Total Duration: $($Duration) seconds" -ForegroundColor Green
Write-Host "-------------------------`n"
}
Write-Host "Benchmark Results" -ForegroundColor Cyan
if ($SimpleMode) {
Write-Host "Total Duration: $($Duration) seconds" -ForegroundColor Green
} else {
Write-Host "Output file info: $($w) x $($h) ($($mpix) MPix)"
Write-Host "Start: $($Start.ToString('HH:mm:ss.fff'))"
Write-Host "End: $($End.ToString('HH:mm:ss.fff'))"
Write-Host "Total Duration: $($Duration) seconds" -ForegroundColor Green
}
Write-Host "-------------------------`n"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment