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

Poor performance of ContentType header rendering #2573

Closed
kyri-petrou opened this issue Dec 31, 2023 · 5 comments
Closed

Poor performance of ContentType header rendering #2573

kyri-petrou opened this issue Dec 31, 2023 · 5 comments
Labels
💎 Bounty bug Something isn't working 💰 Rewarded

Comments

@kyri-petrou
Copy link
Collaborator

Describe the bug
Hi there 👋. I was going through some profiling data of a web-app and there was a disproportionally high % of CPU being spent on the zio.http.Header$ContentType.renderedValueAsCharSequence() method (up to 5% of the application's total CPU time)

To Reproduce
Using JMH:

package example

import org.openjdk.jmh.annotations.*
import zio.http.*

import java.util.concurrent.TimeUnit

@State(Scope.Thread)
@BenchmarkMode(Array(Mode.Throughput))
@OutputTimeUnit(TimeUnit.SECONDS)
@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS)
@Fork(1)
class ContentTypeRenderingBenchmark {

  private val header = Header.ContentType(MediaType.application.json)

  @Benchmark
  def rendered(): Unit =
    for _ <- 1 to 10_000 do header.renderedValue

  @Benchmark
  def interpolation(): Unit =
    for _ <- 1 to 10_000 do s"${header.mediaType.mainType}/${header.mediaType.subType}"
}

Results:

[info] Benchmark                                     Mode  Cnt     Score     Error  Units
[info] ContentTypeRenderingBenchmark.interpolation  thrpt    5  7898.494 ± 270.269  ops/s
[info] ContentTypeRenderingBenchmark.rendered       thrpt    5    62.329 ±   0.772  ops/s

Expected behaviour
I understand there is some additional logic needed in rendering the content type fully (charset, boundaries), but I would expect header.renderedValue's performance to be somewhat similar to using string interpolation

Additional context
A workaround to the issue is to use .untyped on the header, as that forces the rendered value to be cached. However, that does not work in cases where the content type header is dynamically created

@jdegoes
Copy link
Member

jdegoes commented Jan 6, 2024

/bounty $150

Copy link

algora-pbc bot commented Jan 6, 2024

💎 $150 bounty created by ZIO
🙋 If you start working on this, comment /attempt #2573 to notify everyone
👉 To claim this bounty, submit a pull request that includes the text /claim #2573 somewhere in its body
📝 Before proceeding, please make sure you can receive payouts in your country
💵 Payment arrives in your account 2-5 days after the bounty is rewarded
💯 You keep 100% of the bounty award
🙏 Thank you for contributing to zio/zio-http!

Attempt Started (GMT+0) Solution
🟢 @kyri-petrou Jan 6, 2024, 11:31:51 PM #2597

@kyri-petrou
Copy link
Collaborator Author

kyri-petrou commented Jan 6, 2024

/attempt #2573

Options

Copy link

algora-pbc bot commented Jan 7, 2024

💡 @kyri-petrou submitted a pull request that claims the bounty. You can visit your bounty board to reward.

Copy link

algora-pbc bot commented Jan 7, 2024

🎉🎈 @kyri-petrou has been awarded $150! 🎈🎊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💎 Bounty bug Something isn't working 💰 Rewarded
Projects
None yet
Development

No branches or pull requests

3 participants