Skip to content

🩹 [Patch]: Module startup is faster and performance checks are reproducible#69

Open
Marius Storhaug (MariusStorhaug) wants to merge 12 commits into
mainfrom
benchmark-module-performance
Open

🩹 [Patch]: Module startup is faster and performance checks are reproducible#69
Marius Storhaug (MariusStorhaug) wants to merge 12 commits into
mainfrom
benchmark-module-performance

Conversation

@MariusStorhaug

@MariusStorhaug Marius Storhaug (MariusStorhaug) commented Jul 19, 2026

Copy link
Copy Markdown
Member

Module startup is now faster and performance regressions are easier to catch because the import path was optimized and repeatable benchmark tooling is included in the repository.

Changed: Faster module startup

Cold module import is significantly faster in fresh PowerShell sessions, and parallel session startup is also reduced, so common CLI and automation entry points spend less time on initialization.

Metric Before After Δ
Cold import (fresh pwsh) 66.7 ms 42.3 ms −37%
Parallel runspaces ×4 (import + roundtrip) 43.5 ms 28.1 ms −35%
Per-op (seal / open / keypair) 104 / 104–121 / 49 µs 99 / 100–112 / 46 µs −4–7%

Changed: Reproducible performance verification

The repository now includes benchmark scripts for cold import timing, per-operation stopwatch measurements, and Profiler traces, so performance changes can be validated the same way in future PRs.

Technical Details

  • Kept the Import-Module assembly-load approach after evaluating alternatives because Add-Type -Path and Assembly.LoadFrom were slower on measured runs.
  • Optimized import-time initialization by using a direct runtime path combine operation and avoiding redundant interop calls for fixed crypto_box size constants.
  • Added tools/benchmark scripts for local module assembly, stopwatch benchmarks, import benchmarks, and profiler traces, then cleaned them to satisfy linter rules.
  • Public interfaces remain unchanged, full test suite remains green, and multi-session behavior (parallel runspaces/processes) is preserved.
  • Implementation progress for the linked issue is complete: benchmarked load strategies, selected the fastest safe path, and documented the decision in this PR.
Related issues

Initialize Sodium once during module import and derive byte-array public keys directly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exercise concurrent runspace and process imports plus direct byte-array key derivation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown

Super-linter summary

Language Validation result
CHECKOV Pass ✅
CSHARP Pass ✅
GITHUB_ACTIONS Pass ✅
GITLEAKS Pass ✅
GIT_MERGE_CONFLICT_MARKERS Pass ✅
MARKDOWN Pass ✅
NATURAL_LANGUAGE Pass ✅
POWERSHELL Pass ✅
PRE_COMMIT Pass ✅
SPELL_CODESPELL Pass ✅
TRIVY Pass ✅
YAML Pass ✅

All files and directories linted successfully

For more information, see the GitHub Actions workflow run

Powered by Super-linter

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the steady-state performance of Sodium’s PowerShell cryptographic commands by removing repeated per-command initialization overhead and reducing avoidable command-layer conversions, while keeping existing command parameters and return formats intact for current callers.

Changes:

  • Removes redundant per-command Initialize-Sodium calls from keygen, public-key derivation, encryption, and decryption command wrappers (relying on module import-time initialization instead).
  • Adds a managed DerivePublicKey(string privateKeyBase64) -> byte[] API and updates Get-SodiumPublicKey -AsByteArray to return the derived byte array directly.
  • Expands Pester coverage for byte-array public-key derivation and parallel module load/crypto round-trips (runspaces + processes).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Sodium.Tests.ps1 Adds coverage for byte-array public-key derivation and parallel module loading/round-trips.
src/functions/public/New-SodiumKeyPair.ps1 Removes per-command initialization to reduce overhead.
src/functions/public/Get-SodiumPublicKey.ps1 Returns a managed byte[] directly for -AsByteArray and keeps Base64 output path intact.
src/functions/public/ConvertTo-SodiumSealedBox.ps1 Removes per-command initialization to reduce overhead.
src/functions/public/ConvertFrom-SodiumSealedBox.ps1 Removes per-command initialization to reduce overhead.
PSModule/Sodium/Sodium.cs Introduces DerivePublicKey returning byte[] and re-implements Base64 derivation via the new method.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/Sodium.Tests.ps1 Outdated
Exercise idempotent initialization, buffer-size caching, unsupported platforms, and missing runtime diagnostics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

tests/Sodium.Tests.ps1:171

  • Get-SodiumPublicKey -AsByteArray returns a byte[], but this assertion checks for a single byte. This will fail and also contradicts the subsequent [Convert]::ToBase64String($derivedPublicKey) call which requires a byte[].
        It 'Get-SodiumPublicKey - Returns the public key as a byte array' {
            $keyPair = New-SodiumKeyPair
            $derivedPublicKey = Get-SodiumPublicKey -PrivateKey $keyPair.PrivateKey -AsByteArray

            $derivedPublicKey | Should -BeOfType ([byte])
            [Convert]::ToBase64String($derivedPublicKey) | Should -Be $keyPair.PublicKey

Isolate untriggerable native-load diagnostics, simulate the Windows registry branch, and assert byte-array output without pipeline enumeration.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Extract runtime identifier resolution for deterministic cross-platform tests and preserve byte arrays as single pipeline objects.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Comment thread tests/Sodium.Tests.ps1
Shadow the platform flag so the cross-platform test executes the mocked registry lookup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

@MariusStorhaug
Marius Storhaug (MariusStorhaug) marked this pull request as ready for review July 19, 2026 03:46
@MariusStorhaug Marius Storhaug (MariusStorhaug) changed the title 🩹 [Patch]: Cryptographic commands run up to 30% faster 🩹 [Patch]: Cryptographic commands run up to 21% faster Jul 19, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use System.IO.Path::Combine for assembly path resolution and cache fixed Sodium key/seal/seed byte sizes without extra native calls during import. On this machine, cold import dropped from ~71.1 ms baseline to ~54.5 ms in repeated runs (~23% faster), with all tests still passing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@MariusStorhaug Marius Storhaug (MariusStorhaug) changed the title 🩹 [Patch]: Cryptographic commands run up to 21% faster 🩹 [Patch]: Faster module import and benchmark tooling Jul 19, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@MariusStorhaug Marius Storhaug (MariusStorhaug) changed the title 🩹 [Patch]: Faster module import and benchmark tooling 🩹 [Patch]: Module startup is faster and performance checks are reproducible Jul 19, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Perf: Evaluate assembly load strategy vs Import-Module for binary dependency load

2 participants