Skip to content

Cut ~59s from every offline install by not shelling out to Get-Disk - #66

Merged
RobThePCGuy merged 1 commit into
masterfrom
perf/disk-number-diskpart
Jul 28, 2026
Merged

Cut ~59s from every offline install by not shelling out to Get-Disk#66
RobThePCGuy merged 1 commit into
masterfrom
perf/disk-number-diskpart

Conversation

@RobThePCGuy

Copy link
Copy Markdown
Owner

The finding

_disk_number() resolved the attached VHD's disk index via
powershell -NoProfile -Command "(Get-Disk | ...).Number". Measured on a real
instance, that one call costs ~17s -- and almost none of it is disk work. It is
PowerShell cold-loading the Storage/CIM providers on every spawn.

_Attached pays it twice: once to resolve the device, once when _detach
verifies the disk is gone. Broken down, per _Attached block:

Step Time
diskpart attach vdisk (the actual disk work) 1.6s
_disk_number()Get-Disk 17.6s
_partition_offset() (MBR read) 0.05s
detach (calls _disk_number again) 19.0s

An install attaches Root.vhd and Data.vhdx separately, so the user waited
~76s, roughly 70s of it in Get-Disk.

Worth recording the thing that wasn't slow: the e2fsck integrity pass, which
looked like the obvious suspect, is 0.27s. It scales with used inodes and blocks
(~4,400 files), not image size. Removing it would save nothing and cost the check
that catches a bad debugfs write.

The change

diskpart already knows the answer and prints it as Associated disk#: 2. Ask it
instead -- one diskpart run, ~1.6s. Verified to agree with Get-Disk in both
states:

attached detached
diskpart parse 2 in 1.59s None in 1.62s
Get-Disk 2 in 17.07s None in 17.33s

The detached case is the one that matters -- _detach() treats None as proof the
disk released, so a fast path that returned None for an attached disk would let
detach report success on a still-mounted image.

Associated disk# is English diskpart text, so the parser reports whether it
understood the output at all, and we fall back to Get-Disk when it did not. A
localised Windows keeps working at the old speed instead of failing silently.

Result

Measured through the real code path, full attach/detach cycle:

Before After
Data.vhdx ~38s 8.55s
Root.vhd ~38s 8.20s
Per install ~76s 16.75s

~59s off every install, and again off every uninstall.

Tests

tests/test_disk_number.py pins the behaviour that made the fast path safe: agreement
with Get-Disk attached and detached, and -- most importantly -- that unrecognised
output falls back rather than being mistaken for "detached".

Full suite: 307 passed.

_disk_number() resolved the attached VHD's disk index with
`powershell -NoProfile -Command "(Get-Disk | ...).Number"`. Measured on a real
instance, that call costs ~17s -- almost none of it disk work. It is PowerShell
cold-loading the Storage/CIM providers on every spawn, and _Attached pays it
twice: once to resolve the device, once when _detach verifies the disk is gone.

Per _Attached block:

    diskpart attach vdisk      1.6s   <- the actual disk work
    _disk_number (Get-Disk)   17.6s
    _partition_offset          0.05s
    detach (Get-Disk again)   19.0s

An install attaches Root.vhd and Data.vhdx separately, so a user waited ~76s,
about 70s of which was Get-Disk. For contrast, the e2fsck integrity pass that
looked like the expensive step is 0.27s -- it scales with used inodes and
blocks (~4400 files), not image size.

diskpart already knows the answer and prints it as `Associated disk#: 2`, so ask
it instead: one diskpart run, ~1.6s. Verified to agree with Get-Disk in both
states, attached and detached -- the detached case matters because _detach()
treats None as proof the disk released.

`Associated disk#` is English diskpart text, so the parse reports whether it
understood the output at all and we fall back to Get-Disk when it did not. A
localised Windows keeps working at the old speed rather than silently reading
"attached" as "gone", which would let _detach() claim success on a still-mounted
image.

Measured through the real code path, full attach/detach cycle:

    Data.vhdx   ~38s -> 8.55s
    Root.vhd    ~38s -> 8.20s
    per install  ~76s -> 16.75s

Full suite: 307 passed.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a98c7e257

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ext4_symlink.py
Comment on lines +217 to +218
if _ASSOC_DISK_FIELD_RE.search(out):
return None, True # field present, no number => detached

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Anchor the disk field match to its output line

On localized Windows where the BlueStacks data directory contains the literal Associated disk# (a valid Windows folder name), detail vdisk still prints that text as part of the VHD filename even though the actual field label is translated. This unanchored search therefore marks the output as parsed and returns None instead of falling back to Get-Disk, causing attached disks to be reported as missing and potentially making _detach() report success after a failed detach. Match a complete field line, including its delimiter, rather than any occurrence in the output.

Useful? React with 👍 / 👎.

@RobThePCGuy

RobThePCGuy commented Jul 28, 2026 via email

Copy link
Copy Markdown
Owner Author

@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • Anchored the Associated disk# regular expressions to complete DiskPart output lines and required the field delimiter, preventing filename text from being mistaken for a parsed field. Attached and detached states remain supported. ext4_symlink.pyL194-L201 ext4_symlink.pyL218-L225
  • Added a regression fixture and test proving that localized DiskPart output containing Associated disk# within the VHD filename falls back safely to Get-Disk. tests/test_disk_number.pyL41-L46 tests/test_disk_number.pyL77-L82
  • Committed the changes as 017ae8d (Anchor diskpart associated disk parsing) and created the follow-up pull request titled “Anchor diskpart associated-disk parsing to field lines.”

Testing

  • git diff --check
  • PYTHONPATH="$tmp${PYTHONPATH:+:$PYTHONPATH}" pytest -q tests/test_disk_number.py — 6 passed.
  • ⚠️ PYTHONPATH="$tmp${PYTHONPATH:+:$PYTHONPATH}" pytest -q — full-suite collection is unavailable in this Linux environment because the Windows-only ctypes.WinDLL API and dependencies including PyQt5 and psutil are unavailable.

View task →

@RobThePCGuy
RobThePCGuy merged commit eea6786 into master Jul 28, 2026
5 checks passed
@RobThePCGuy
RobThePCGuy deleted the perf/disk-number-diskpart branch July 28, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant