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

Optimize RichTextCodec #2597

Merged
merged 6 commits into from
Jan 7, 2024
Merged

Conversation

kyri-petrou
Copy link
Collaborator

/claim #2573

I know the issue was only for fixing the encoding performance, but as a welcoming side-effect these changes also improve the overall performance of the RichTextCodec. Also, the rendering of the content-type header is now cached (in a lazy val), so users that reuse the same instance of a ContentType will not incur any runtime overhead for encoding it on repeated requests.

Breaking(?) changes:

  • RichTextCodec is now a sealed abstract class instead of a sealed trait. This improved performance marginally although I'm happy to revert it if you prefer to have it as a sealed trait instead.
  • The description of repeated codecs was changed (see changed unit test). The main reasoning for this is that it was very hard to replicate the same error message now that the implementation of repeated codecs is different. I saw that in the unit test there was a recommendation for changing the description (which personally I think is clearer) and since that was easy to do with the new Repeated implementation I went with that

Benchmark results

Summary

Parsing:

  • ~5x increased throughput
  • ~10x reduced memory allocations

Encoding:

  • ~15x increased throughput
  • ~20x reduced memory allocations

JMH results (click to expand)

main branch:

[info] Benchmark                                                                 Mode  Cnt       Score      Error   Units
[info] ProbeContentTypeBenchmark.benchmarkParseContentType                      thrpt    5  110070.585 ±  371.643   ops/s
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.alloc.rate        thrpt    5    3551.249 ±   12.025  MB/sec
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.alloc.rate.norm   thrpt    5   33832.021 ±    0.001    B/op
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.count             thrpt    5     168.000             counts
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.time              thrpt    5      81.000                 ms
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType                     thrpt    5  294430.289 ± 1231.373   ops/s
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.alloc.rate       thrpt    5    3272.757 ±   13.771  MB/sec
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.alloc.rate.norm  thrpt    5   11656.008 ±    0.001    B/op
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.count            thrpt    5     198.000             counts
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.time             thrpt    5      91.000                 ms

PR:

[info] ProbeContentTypeBenchmark.benchmarkParseContentType                      thrpt    5   567862.566 ± 45382.116   ops/s
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.alloc.rate        thrpt    5     1732.915 ±   138.500  MB/sec
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.alloc.rate.norm   thrpt    5     3200.004 ±     0.001    B/op
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.count             thrpt    5      155.000              counts
[info] ProbeContentTypeBenchmark.benchmarkParseContentType:gc.time              thrpt    5       59.000                  ms
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType                     thrpt    5  4756430.171 ± 53198.579   ops/s
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.alloc.rate       thrpt    5     2104.663 ±    23.531  MB/sec
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.alloc.rate.norm  thrpt    5      464.000 ±     0.001    B/op
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.count            thrpt    5      193.000              counts
[info] ProbeContentTypeBenchmark.benchmarkRenderContentType:gc.time             thrpt    5       71.000                  ms

Copy link

algora-pbc bot commented Jan 7, 2024

💵 To receive payouts, sign up on Algora, link your Github account and connect with Stripe/Alipay.

@kyri-petrou kyri-petrou marked this pull request as draft January 7, 2024 06:42
@codecov-commenter
Copy link

codecov-commenter commented Jan 7, 2024

Codecov Report

Attention: 5 lines in your changes are missing coverage. Please review.

Comparison is base (f4b2b3f) 64.23% compared to head (d0e61af) 64.39%.

Files Patch % Lines
.../src/main/scala/zio/http/codec/RichTextCodec.scala 94.25% 5 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2597      +/-   ##
==========================================
+ Coverage   64.23%   64.39%   +0.16%     
==========================================
  Files         140      140              
  Lines        8358     8407      +49     
  Branches     1604     1608       +4     
==========================================
+ Hits         5369     5414      +45     
- Misses       2989     2993       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kyri-petrou kyri-petrou marked this pull request as ready for review January 7, 2024 08:24
@jdegoes jdegoes merged commit 80d384d into zio:main Jan 7, 2024
14 checks passed
@kyri-petrou kyri-petrou deleted the optimize-rich-text-codec branch January 7, 2024 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants