Skip to content

avoid isinstance() checks in version comparisons for a mild performance improvement#51367

Open
cosmicexplorer wants to merge 3 commits intospack:developfrom
cosmicexplorer:version-isinstance-type
Open

avoid isinstance() checks in version comparisons for a mild performance improvement#51367
cosmicexplorer wants to merge 3 commits intospack:developfrom
cosmicexplorer:version-isinstance-type

Conversation

@cosmicexplorer
Copy link
Copy Markdown
Contributor

@cosmicexplorer cosmicexplorer commented Sep 25, 2025

Problem

See #51365. isinstance() checks in version comparisons are a mild performance hotspot.

Solution

Convert every isinstance() check in version_types.py into an is pointer equality against type(...).

Result

Very mild performance improvment (I'm seeing 11%, but it depends upon the run).

@cosmicexplorer cosmicexplorer force-pushed the version-isinstance-type branch 2 times, most recently from 4d8c856 to 96b2473 Compare September 25, 2025 15:54
@cosmicexplorer
Copy link
Copy Markdown
Contributor Author

Tests are failing on matching str subclasses, particularly syaml_str—allowing for those with issubclass() should not take away from the performance gains.

@cosmicexplorer cosmicexplorer marked this pull request as ready for review September 25, 2025 16:19
@haampie
Copy link
Copy Markdown
Member

haampie commented Sep 25, 2025

shaved off half the runtime

of what exactly? I see a 3.5% speedup in setup time, and a 0.4% speedup overall when comparing spack solve --timers --fresh cmake before/after this PR. That's good, but curious where you get the "half as a long" from.

@cosmicexplorer
Copy link
Copy Markdown
Contributor Author

cosmicexplorer commented Sep 27, 2025

That's confusing. I had been getting some pretty reliable results from switching over to develop and then running the profile script which concretized icu4c cxxstd=17. This change was turning 48 seconds => 24 seconds, and 30 seconds => 15 seconds. I'm now not getting that at all from develop, on spack spec or the profile script. I had been getting 50-second spack runtimes very reliably and it was part of why I thought this was so important to follow up on.

@cosmicexplorer cosmicexplorer changed the title avoid isinstance() checks in version comparisons for a surprisingly significant performance improvement avoid isinstance() checks in version comparisons for a mild performance improvement Sep 27, 2025
@cosmicexplorer
Copy link
Copy Markdown
Contributor Author

Like, I have two snakeviz windows open right now showing 30s/48s runtimes for spack spec from yesterday. I truly have no clue what changed.

@cosmicexplorer
Copy link
Copy Markdown
Contributor Author

Kind of upset about this. I was at first still getting about an 11% improvement (after running several times to alleviate e.g. page cache issues) but that's not happening anymore either and I'm getting about the performance you describe as well. I had been getting 50-second runtimes extremely reliably and I don't know where those were coming from now.

@haampie
Copy link
Copy Markdown
Member

haampie commented Sep 29, 2025

Solver performance is deterministic for fixed input, but can easily be 2x slower if some new fact is added or the same facts are presented in a different order.

For benchmarking of the Python side you can best look at "setup" reported by spack solve --timers, which is deterministic enough.

For end-to-end performance testing it's best to use a statistical test, see this repo: https://github.com/spack/spack-benchmark. It's very time consuming to run a full benchmark with multiple samples per spec (i.e. multiple shuffles of input data), so in your case I would just look at "setup" time.

@cosmicexplorer cosmicexplorer force-pushed the version-isinstance-type branch from cf1186b to 3ab1b43 Compare October 10, 2025 09:29
@cosmicexplorer cosmicexplorer force-pushed the version-isinstance-type branch from 3ab1b43 to 71c05e2 Compare October 25, 2025 15:58
vbrunini added a commit to vbrunini/spack that referenced this pull request Nov 6, 2025
By using a cache for Spec objects and reducing the number of copies
of Spec objects being done. Combined with spack#51367 and the reduced install
task sleep time from spack#51491 this reduces the time for a no-op install of
a development environment with 94 packages (including dependencies) from 8s
to 2.8s for me. It also provides a similar reduction in time for
`spack build-env --dump env.txt mypkg` which we frequently use to start a
shell with the build environment.

Signed-off-by: Victor Brunini <[email protected]>
vbrunini added a commit to vbrunini/spack that referenced this pull request Nov 8, 2025
Combined with spack#51535, spack#51536, spack#51367 and the reduced install
task sleep time from spack#51491 this reduces the time for a no-op install of
a development environment with 94 packages (including dependencies) from 8s
to 2.8s for me. It also provides a similar reduction in time for
`spack build-env --dump env.txt mypkg` which we frequently use to start a
shell with the build environment.

Signed-off-by: Victor Brunini <[email protected]>
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.

2 participants