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

Micro-optimization for Schedule #7532

Merged
merged 1 commit into from
Nov 17, 2022

Conversation

ollyw
Copy link
Contributor

@ollyw ollyw commented Nov 17, 2022

7% improvement in Schedule. Useful for low periodic timers, such as those used in ZStream.groupedWithin.

It is fairly rare that durations of timer are low enough to notice the difference in an overall application, but with a high-throughput stream that also wants to keep latency low for the downstream consumer, it is noticeable. Removing the throw stops having to fill a stack trace and throw in the normally code path where the Schedule upper-bound is OffsetDateTime.Max. An alternative change could be to substract the delta from Max and compare with interval.end. However this approach has two downsides. 1) it is not clear from the original code if overflow is the only cause of exception. 2) there is more work done on the happy path to do the subtractions then to simply compare.

Below is a benchmark showing an (unrealistically) low duration on pretty fast desktop that shows a 7% uplift in ops/s:

 @Benchmark
  def zioGroupWithinShortDuration: Long = {
    val result = ZStream.tick(Duration(10, TimeUnit.MICROSECONDS))
      .groupedWithin(100, Duration(1, TimeUnit.MICROSECONDS))
      .take(10)
      .runCount

    unsafeRun(result)
  }

With the current ZIO head:

[info] Result "zio.StreamBenchmarks.zioGroupWithinShortDuration":
[info] Benchmark                             (chunkCount)  (chunkSize)  (parChunkSize)   Mode  Cnt    Score   Error  Units
[info] StreamBenchmarks.zioGroupWithinShortDuration          1000          500              50  thrpt   25  506.861 ± 4.498  ops/s

With the patched version

[info] Result "zio.StreamBenchmarks.zioGroupWithinShortDuration":
[info] Benchmark                             (chunkCount)  (chunkSize)  (parChunkSize)   Mode  Cnt    Score   Error  Units
[info] StreamBenchmarks.zioGroupWithinShortDuration          1000          500              50  thrpt   25  541.499 ± 2.647  ops/s

I didn't add the benchmark to the StreamBenchmarks as I am not sure it is worth carrying forward for such a specific case, but happy to add/refine if you fancy merging the PR

This optimization is low risk, albeit for little returns for most ZIO users.

7% improvement in Schedule. Useful for low periodic timers, such as those
used in ZStream.groupedWithin
Copy link
Contributor

@adamgfraser adamgfraser left a comment

Choose a reason for hiding this comment

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

Thank you! 🙏

@ollyw
Copy link
Contributor Author

ollyw commented Nov 17, 2022

The CI appears to have failed on something unrelated. Perhaps a flaky test?

https://github.com/zio/zio/actions/runs/3488622911/jobs/5838949022#step:7:6655

@adamgfraser adamgfraser merged commit 5119c8e into zio:series/2.x Nov 17, 2022
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.

None yet

2 participants