Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: create directories up front #533

Merged
merged 4 commits into from
May 14, 2024

Conversation

baszalmstra
Copy link
Collaborator

When linking packages a lot of time is spent creating directories as this flamegraph highlights:

image

Most of the time is spent checking if a directory (or its parents) already exists. However, we already know upfront all the directories that need to be created so why not do that? Well, say no more! That is exactly what this PR does!

New situation:

image

Its completely gone. Great success! 👍

In my preliminary dead simple benchmarks, this can easily save 20% of installation times.

@baszalmstra
Copy link
Collaborator Author

This PR is still open because for @ruben-arts this was actually slowing down his installation. We still need to investigate more.

@baszalmstra
Copy link
Collaborator Author

@ruben-arts When you have some time shall we take another look at debugging this? I tested it this weekend and on windows this is a pretty big win.

@baszalmstra
Copy link
Collaborator Author

Here are some benchmarks from my windows machine:

❯ hyperfine --shell nu --prepare "rm -rf .prefix" "target/release/rattler_fast.exe create python" "target/release/rattler.exe create python"
Benchmark 1: target/release/rattler_fast.exe create python
  Time (mean ± σ):      1.303 s ±  0.314 s    [User: 0.472 s, System: 0.328 s]
  Range (min … max):    0.961 s …  1.732 s    10 runs

Benchmark 2: target/release/rattler.exe create python
  Time (mean ± σ):      1.535 s ±  0.420 s    [User: 0.414 s, System: 0.374 s]
  Range (min … max):    1.076 s …  2.412 s    10 runs

Summary
  target/release/rattler_fast.exe create python ran
    1.18 ± 0.43 times faster than target/release/rattler.exe create python
❯ hyperfine --shell nu -w 3 --prepare "rm -rf .prefix" "target/release/rattler_fast.exe create jupyterlab" "target/release/rattler.exe create jupyterlab"
Benchmark 1: target/release/rattler_fast.exe create jupyterlab
  Time (mean ± σ):      5.854 s ±  0.538 s    [User: 2.174 s, System: 0.871 s]
  Range (min … max):    5.177 s …  6.880 s    10 runs

Benchmark 2: target/release/rattler.exe create jupyterlab
  Time (mean ± σ):      6.287 s ±  0.623 s    [User: 2.271 s, System: 1.435 s]
  Range (min … max):    5.346 s …  7.015 s    10 runs

Summary
  target/release/rattler_fast.exe create jupyterlab ran
    1.07 ± 0.15 times faster than target/release/rattler.exe create jupyterlab 

@baszalmstra
Copy link
Collaborator Author

Under WSL:

➜ hyperfine -w 3 --prepare "rm -rf .prefix" "target/release/rattler_fast create python" "target/release/rattler create python"
Benchmark 1: target/release/rattler_fast create python
  Time (mean ± σ):     690.9 ms ±  18.5 ms    [User: 786.7 ms, System: 1411.9 ms]
  Range (min … max):   672.8 ms … 738.0 ms    10 runs

Benchmark 2: target/release/rattler create python
  Time (mean ± σ):     704.9 ms ±  43.2 ms    [User: 870.0 ms, System: 1782.2 ms]
  Range (min … max):   654.2 ms … 798.4 ms    10 runs

Summary
  'target/release/rattler_fast create python' ran
    1.02 ± 0.07 times faster than 'target/release/rattler create python'
➜ hyperfine -w 3 --prepare "rm -rf .prefix" "target/release/rattler_fast create jupyterlab" "target/release/rattler create jupyterlab"
Benchmark 1: target/release/rattler_fast create jupyterlab
  Time (mean ± σ):      2.705 s ±  0.026 s    [User: 2.800 s, System: 4.408 s]
  Range (min … max):    2.663 s …  2.741 s    10 runs

Benchmark 2: target/release/rattler create jupyterlab
  Time (mean ± σ):      2.708 s ±  0.032 s    [User: 2.842 s, System: 6.267 s]
  Range (min … max):    2.679 s …  2.777 s    10 runs

Summary
  'target/release/rattler_fast create jupyterlab' ran
    1.00 ± 0.02 times faster than 'target/release/rattler create jupyterlab'

Looks like at least under WSL there is hardly any difference.

@ruben-arts
Copy link
Collaborator

On my windows machine:

❯ hyperfine --shell nu --prepare "rm -rf .prefix" "target/release/rattler_fast.exe create python" "target/release/rattler.exe create python"
Benchmark 1: target/release/rattler_fast.exe create python
  Time (mean ± σ):      1.637 s ±  0.024 s    [User: 0.501 s, System: 0.679 s]
  Range (min … max):    1.597 s …  1.675 s    10 runs

Benchmark 2: target/release/rattler.exe create python
  Time (mean ± σ):      1.740 s ±  0.034 s    [User: 0.521 s, System: 0.768 s]
  Range (min … max):    1.694 s …  1.787 s    10 runs

Summary
  target/release/rattler_fast.exe create python ran
    1.06 ± 0.03 times faster than target/release/rattler.exe create python

@ruben-arts
Copy link
Collaborator

On my windows machine with wsl

~/development/rattler> hyperfine --shell nu --prepare "rm -rf .prefix" "target/release/rattler create python" "target/release/rattler_slow create python"
Benchmark 1: target/release/rattler create python
  Time (mean ± σ):     846.2 ms ±  24.8 ms    [User: 926.7 ms, System: 967.0 ms]
  Range (min … max):   821.7 ms … 894.6 ms    10 runs

Benchmark 2: target/release/rattler_slow create python
  Time (mean ± σ):     859.0 ms ±  50.4 ms    [User: 968.9 ms, System: 1332.6 ms]
  Range (min … max):   812.5 ms … 952.1 ms    10 runs

Summary
  target/release/rattler create python ran
    1.02 ± 0.07 times faster than target/release/rattler_slow create python

@ruben-arts
Copy link
Collaborator

And for completeness on my linux beast:

➜ hyperfine --prepare "rm -rf .prefix" "target/release/rattler create python" "target/release/rattler_slow create python"
Benchmark 1: target/release/rattler create python
  Time (mean ± σ):     917.9 ms ±  44.7 ms    [User: 1107.3 ms, System: 828.9 ms]
  Range (min … max):   878.7 ms … 1008.0 ms    10 runs
 
Benchmark 2: target/release/rattler_slow create python
  Time (mean ± σ):     946.0 ms ±  35.1 ms    [User: 1191.0 ms, System: 914.6 ms]
  Range (min … max):   905.1 ms … 1008.5 ms    10 runs
 
Summary
  target/release/rattler create python ran
    1.03 ± 0.06 times faster than target/release/rattler_slow create python

@baszalmstra baszalmstra merged commit 55871a7 into conda:main May 14, 2024
14 checks passed
@baszalmstra baszalmstra deleted the perf/create_directories_up_front branch May 14, 2024 13:37
@baszalmstra baszalmstra mentioned this pull request May 14, 2024
This was referenced May 22, 2024
baszalmstra added a commit that referenced this pull request May 27, 2024
## 🤖 New release
* `rattler`: 0.25.0 -> 0.26.0
* `rattler_conda_types`: 0.23.1 -> 0.24.0
* `rattler_package_streaming`: 0.20.10 -> 0.21.0
* `rattler_networking`: 0.20.7 -> 0.20.8
* `rattler_lock`: 0.22.7 -> 0.22.8
* `rattler_repodata_gateway`: 0.20.1 -> 0.20.2
* `rattler_solve`: 0.22.0 -> 0.23.0
* `rattler_index`: 0.19.12 -> 0.19.13
* `rattler_shell`: 0.20.4 -> 0.20.5
* `rattler_virtual_packages`: 0.19.11 -> 0.19.12

<details><summary><i><b>Changelog</b></i></summary><p>

## `rattler`
<blockquote>

##
[0.26.0](rattler-v0.25.0...rattler-v0.26.0)
- 2024-05-27

### Fixed
- improve progress bar duration display
([#680](#680))

### Other
- introducing the installer
([#664](#664))
- create directories up front
([#533](#533))
</blockquote>

## `rattler_conda_types`
<blockquote>

##
[0.24.0](rattler_conda_types-v0.23.1...rattler_conda_types-v0.24.0)
- 2024-05-27

### Added
- removed Ord and more
([#673](#673))
- always store purls as a key in lock file
([#669](#669))
- add solve strategies
([#660](#660))

### Fixed
- make topological sorting support fully cyclic dependencies
([#678](#678))
</blockquote>

## `rattler_package_streaming`
<blockquote>

##
[0.21.0](rattler_package_streaming-v0.20.10...rattler_package_streaming-v0.21.0)
- 2024-05-27

### Other
- introducing the installer
([#664](#664))
</blockquote>

## `rattler_networking`
<blockquote>

##
[0.20.8](rattler_networking-v0.20.7...rattler_networking-v0.20.8)
- 2024-05-27

### Other
- introducing the installer
([#664](#664))
</blockquote>

## `rattler_lock`
<blockquote>

##
[0.22.8](rattler_lock-v0.22.7...rattler_lock-v0.22.8)
- 2024-05-27

### Added
- removed Ord and more
([#673](#673))
- always store purls as a key in lock file
([#669](#669))
</blockquote>

## `rattler_repodata_gateway`
<blockquote>

##
[0.20.2](rattler_repodata_gateway-v0.20.1...rattler_repodata_gateway-v0.20.2)
- 2024-05-27

### Fixed
- result grouped by subdir instead of channel
([#666](#666))

### Other
- introducing the installer
([#664](#664))
</blockquote>

## `rattler_solve`
<blockquote>

##
[0.23.0](rattler_solve-v0.22.0...rattler_solve-v0.23.0)
- 2024-05-27

### Added
- removed Ord and more
([#673](#673))
- always store purls as a key in lock file
([#669](#669))
- add solve strategies
([#660](#660))

### Fixed
- result grouped by subdir instead of channel
([#666](#666))

### Other
- introducing the installer
([#664](#664))
</blockquote>

## `rattler_index`
<blockquote>

##
[0.19.13](rattler_index-v0.19.12...rattler_index-v0.19.13)
- 2024-05-27

### Added
- always store purls as a key in lock file
([#669](#669))
</blockquote>

## `rattler_shell`
<blockquote>

##
[0.20.5](rattler_shell-v0.20.4...rattler_shell-v0.20.5)
- 2024-05-27

### Other
- updated the following local packages: rattler_conda_types
</blockquote>

## `rattler_virtual_packages`
<blockquote>

##
[0.19.12](rattler_virtual_packages-v0.19.11...rattler_virtual_packages-v0.19.12)
- 2024-05-27

### Other
- updated the following local packages: rattler_conda_types
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/MarcoIeni/release-plz/).
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