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

Optimise HttpContentCodec#lookup #3024

Closed
wants to merge 4 commits into from

Conversation

guizmaii
Copy link
Member

@guizmaii guizmaii commented Aug 16, 2024

Copy link
Member

@jdegoes jdegoes left a comment

Choose a reason for hiding this comment

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

Damn you're getting good. 😆

@guizmaii guizmaii force-pushed the optimize_HttpContentCodec_lookup branch from bdc19e3 to 1bfb93e Compare August 16, 2024 11:15
@guizmaii
Copy link
Member Author

@jdegoes Thanks! I'm copying from some of the optimisations I see made by Kyri in ZIO! 🙂

We have a discussion with @987Nabil in Discord tho.
The default implementation of Map#getOrElse is instantiating an Option, which is annoying as it's in the hot path.
So I replaced the scala.Map by a scala.HashMap because its #getOrElse implementation doesn't instantiate any Option:
Screenshot 2024-08-16 at 9 04 43 PM

What's your opinion about that?

@987Nabil
Copy link
Contributor

@jdegoes I was also wondering, if small HashMaps (4 or 5 elements max) are slower then the default map.

@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 65.27%. Comparing base (e9f1c02) to head (3ddc63d).
Report is 44 commits behind head on main.

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

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3024      +/-   ##
==========================================
+ Coverage   64.78%   65.27%   +0.48%     
==========================================
  Files         157      155       -2     
  Lines        9395    10127     +732     
  Branches     1743     1886     +143     
==========================================
+ Hits         6087     6610     +523     
- Misses       3308     3517     +209     

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

@kyri-petrou
Copy link
Collaborator

I might be missing something, but this looks like an ideal situation to use a mutable map instead of an immutable one with a var. What's the reasoning for using an immutable one?

@kyri-petrou
Copy link
Collaborator

I mentioned this on Discord but just putting this here as well for visibility; Most (if not all) immutable Map implementations override the getOrElse implementation on the base Map trait. E.g., Map1:

image

@987Nabil
Copy link
Contributor

@kyri-petrou I don't think in this case it makes any significant difference between var or mutable. Because the writes are probably just a very few. This is read heavy

@kyri-petrou
Copy link
Collaborator

@987Nabil In that case I'd leave the implementation as is then (using Map instead of HashMap)

@kyri-petrou
Copy link
Collaborator

kyri-petrou commented Aug 17, 2024

@guizmaii by the way I recently came across a small trick that might be good to apply here. To avoid the Function0 allocation in getOrElse, you can store the () => null in a val and do this:

val map: Map[String, String] = ???
private val orElseNull: () => String = () => null

map.getOrElse("foo", orElseNull())

This avoids the allocation because () => String and => String are the same thing.

Scala 3 only:
Store the val in the companion object and add the @static annotation to it

@kyri-petrou
Copy link
Collaborator

kyri-petrou commented Aug 17, 2024

@guizmaii I just found out something interesting (or maybe a bug in dotty?). In Scala 2 this optimization works out of the box, but in Scala 3 it only works if you use the @static annotation 🤔

@guizmaii guizmaii marked this pull request as draft August 22, 2024 09:26
@guizmaii guizmaii force-pushed the optimize_HttpContentCodec_lookup branch from 5881cd9 to 6f36929 Compare August 22, 2024 09:37
}

// Required for @static fields
private final class syntax private
Copy link
Member Author

Choose a reason for hiding this comment

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

@kyri-petrou What is this for? Do I need it? 🤔

@guizmaii guizmaii marked this pull request as ready for review August 22, 2024 09:39
@guizmaii
Copy link
Member Author

@987Nabil @kyri-petrou I made the changes you asked for :)

@guizmaii guizmaii force-pushed the optimize_HttpContentCodec_lookup branch from 6f36929 to 8546913 Compare August 23, 2024 00:07
@987Nabil
Copy link
Contributor

@guizmaii I think something of the optimizing is not working with scala js

@guizmaii guizmaii marked this pull request as draft August 23, 2024 09:10
@987Nabil
Copy link
Contributor

@guizmaii I close PRs to have a better overview what is needed for 3.0
Feel free to reopen when it is building

@987Nabil 987Nabil closed this Aug 27, 2024
@guizmaii guizmaii deleted the optimize_HttpContentCodec_lookup branch September 1, 2024 07:51
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.

5 participants