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

Speed up build loading and minimize its IO #653

Merged
merged 2 commits into from
Sep 21, 2018

Conversation

jvican
Copy link
Contributor

@jvican jvican commented Sep 21, 2018

When bloop loads up a build from the configuration files, bloop performs
all the required book-keeping to be able to detect changes on it in the
future and correctly load up the build again if a user runs a command.

We used to implement this feature by checking last modified times and the
checksums produced by zip JDK utilities. However, this approach had several
inconvenients:

  1. It was slow (reloading a build like lichess took 5s in our benchmarks)
  2. It was repeating IO utilities. 3. The checksum taken at the end
    represented the whole build, but we are
    interested in updating the build incrementally only for the
    configuration files that changed instead of updating all the build.

The new approach introduced by this pull request fixes these issues. First,
every configuration file has access to its last modified time and its hash.
Second, it's fast. And third, we minimize IO (get modified time from the
file visitors and read only the configuration files once when we both check
for updates and update the build accordingly).

To prove it, here's the benchmarks after the change:

[info] Benchmark
Mode     Cnt   Score    Error  Units
[info] ProjectBenchmark.loadAkkaProject
sample  107924   0.463 ±  0.002  ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.00
sample           0.408           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.50
sample           0.416           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.90
sample           0.625           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.95
sample           0.718           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.99
sample           1.091           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.999
sample           1.676           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.9999
sample           4.652           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p1.00
sample          12.976           ms/op
[info] ProjectBenchmark.loadLichessProject
sample   60764   0.822 ±  0.003  ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.00
sample           0.750           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.50
sample           0.770           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.90
sample           0.866           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.95
sample           1.260           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.99
sample           1.493           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.999
sample           2.574           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.9999
sample           8.109           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p1.00
sample          18.121           ms/op
[info] ProjectBenchmark.loadSbtProject
sample  208099   0.240 ±  0.001  ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.00
sample           0.228           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.50
sample           0.231           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.90
sample           0.246           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.95
sample           0.266           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.99
sample           0.380           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.999
sample           1.313           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.9999
sample           2.133           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p1.00
sample           5.472           ms/op

The slowest build load is lichess, which consists of 138 configuration
files that took up around 6.8MB of space.

@jvican jvican added performance benchmarks Any change that affects our benchmark suite. ergonomics Any change that affects developer ergonomics and the easiness of use of bloop. labels Sep 21, 2018
@jvican
Copy link
Contributor Author

jvican commented Sep 21, 2018

Note that the benchmarks are for a full load. Most of the times there are no changes in the configuration file and therefore the build reload is skipped.

Here is a screenshot I took from the previous checksum facility:

zip-slow-checksum

When bloop loads up a build from the configuration files, bloop performs
all the required book-keeping to be able to detect changes on it in the
future and correctly load up the build again if a user runs a command.

We used to implement this feature by checking last modified times and
the checksums produced by zip JDK utilities. However, this approach had
several inconvenients:

1. It was slow (reloading a build like lichess took 5s in our benchmarks)
2. It was repeating IO utilities.
3. The checksum taken at the end represented the whole build, but we are
   interested in updating the build incrementally only for the
   configuration files that changed instead of updating all the build.

The new approach introduced by this pull request fixes these issues.
First, every configuration file has access to its last modified time and
its hash. Second, it's fast. And third, we minimize IO (get modified
time from the file visitors and read only the configuration files once
when we both check for updates and update the build accordingly).

To prove it, here's the benchmarks after the change:

```
[info] Benchmark                                                         Mode     Cnt   Score    Error  Units
[info] ProjectBenchmark.loadAkkaProject                                sample  107924   0.463 ±  0.002  ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.00          sample           0.408           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.50          sample           0.416           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.90          sample           0.625           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.95          sample           0.718           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.99          sample           1.091           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.999         sample           1.676           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p0.9999        sample           4.652           ms/op
[info] ProjectBenchmark.loadAkkaProject:loadAkkaProject·p1.00          sample          12.976           ms/op
[info] ProjectBenchmark.loadLichessProject                             sample   60764   0.822 ±  0.003  ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.00    sample           0.750           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.50    sample           0.770           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.90    sample           0.866           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.95    sample           1.260           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.99    sample           1.493           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.999   sample           2.574           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p0.9999  sample           8.109           ms/op
[info] ProjectBenchmark.loadLichessProject:loadLichessProject·p1.00    sample          18.121           ms/op
[info] ProjectBenchmark.loadSbtProject                                 sample  208099   0.240 ±  0.001  ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.00            sample           0.228           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.50            sample           0.231           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.90            sample           0.246           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.95            sample           0.266           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.99            sample           0.380           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.999           sample           1.313           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p0.9999          sample           2.133           ms/op
[info] ProjectBenchmark.loadSbtProject:loadSbtProject·p1.00            sample           5.472           ms/op
```

The slowest build load is lichess, which consists of 138 configuration
files that took up around 6.8MB of space.
@jvican jvican force-pushed the topic/speed-up-build-reloading branch from 8d1b569 to 4ea156a Compare September 21, 2018 11:36
@jvican jvican changed the title Speed up build loading and minimize IO Speed up build loading and minimize its IO Sep 21, 2018
@jvican jvican merged commit 14c8ad9 into master Sep 21, 2018
@tgodzik tgodzik deleted the topic/speed-up-build-reloading branch September 7, 2021 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
benchmarks Any change that affects our benchmark suite. ergonomics Any change that affects developer ergonomics and the easiness of use of bloop. performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant