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 SaturatingLong #36

Merged
merged 1 commit into from
Jan 2, 2025

Conversation

romainguy
Copy link
Contributor

Implement various optimizations to reduce the number of instructions and branches:

  • Outline exception throws to relieve i-cache pressure
  • Fold common comparisons in plus() to go from 94 instructions and 32 branches down to 51 and 5 (94/32 -> 51/5)
  • Similarly simplify times()/div()/rem()/unaryMinus()/toString()
  • Make isInfinite() branchless
  • Inline operators that simply delegate to another operator
  • Inline trivial work that delegates to intrinsics (sign)

Instructions were counted on a Pixel 8 (aarch64) using Android 15.

Implement various optimizations to reduce the number of instructions and branches:
- Outline exception throws to relieve i-cache pressure
- Fold common comparisons in plus() to go from 94 instructions and 32 branches
  down to 51 and 5 (94/32 -> 51/5)
- Similarly simplify times()/div()/rem()/unaryMinus()/toString()
- Make isInfinite() branchless
- Inline operators that simply delegate to another operator
- Inline trivial work that delegates to intrinsics (sign)

Instructions were counted on a Pixel 8 (aarch64) using Android 15.
@@ -153,3 +160,8 @@ internal value class SaturatingLong(val rawValue: Long) {
internal inline val Long.saturated get() = SaturatingLong(this)
internal inline val POSITIVE_INFINITY get() = SaturatingLong(Long.MAX_VALUE)
internal inline val NEGATIVE_INFINITY get() = SaturatingLong(Long.MIN_VALUE)

// TODO: Supply a ProGuard rule to keep this method so it's not inlined
Copy link
Contributor

Choose a reason for hiding this comment

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

Easiest is to put them in src/jvmMain/resources/META-INF/proguard/alchemist.pro. This should cover both JVM usage (e.g., Compose Desktop) and Android.

Copy link
Owner

Choose a reason for hiding this comment

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

#38

@kevincianfarini
Copy link
Owner

This is awesome. Thanks!

@kevincianfarini kevincianfarini merged commit 9737215 into kevincianfarini:trunk Jan 2, 2025
4 checks passed
@romainguy romainguy deleted the rg/optimizations branch January 2, 2025 22:09
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.

3 participants