←back to thread

Scala 3 slowed us down?

(kmaliszewski9.github.io)
261 points kmaliszewski | 2 comments | | HN request time: 0s | source
Show context
_old_dude_ ◴[] No.46183120[source]
In Scala 3, the inline keyword is part of the macro system.

When inline is used on a parameter, it instructs the compiler to inline the expression at the call site. If the expression is substantial, this creates considerable work for the JIT compiler.

Requesting inlining at the compiler level (as opposed to letting the JIT handle it) is risky unless you can guarantee that a later compiler phase will simplify the inlined code.

There's an important behavioral difference between Scala 2 and 3: in 2, @inline was merely a suggestion to the compiler, whereas in 3, the compiler unconditionally applies the inline keyword. Consequently, directly replacing @inline with inline when migrating from 2 to 3 is a mistake.

replies(2): >>46183636 #>>46187828 #
dtech ◴[] No.46183636[source]
Kotlin heavily uses the inline keyword basically everywhere, to get rid of lamdba overhead for functions like map. Basically every stdlib and 3rd part library function that takes a lamdba is inlined.

In general it's a performance benefit and I never heard of performance problems like this. I wonder if combined with Scala's infamous macro system and libraries like quicklens it can generate huge expressions which create this problem.

replies(2): >>46184563 #>>46184763 #
pjmlp ◴[] No.46184763[source]
This is one example why being a guest language isn't optimal.

They should have made use of JVM bytecodes that allow to optimize lambdas away and make JIT aware of them, via invokedynamic and MethodHandle optimizations.

Naturally they cannot rely on them being there, because Kotlin also needs to target ART, JS runtimes, WebAssembly and its own native version.

replies(2): >>46184834 #>>46185183 #
dtech ◴[] No.46184834{3}[source]
Kotlin existed before Java 7 and kept support JVM 1.6 for a long time (mainly because of Android)

Even then, they benchmarked it, and inlining was still faster* than invokedynamic and friends, so they aren't changing it now JVM 1.8+ is a requirement.

* at the expense of expanded bytecode size

replies(1): >>46184939 #
pjmlp ◴[] No.46184939{4}[source]
Java 7 to Java 25 is a world apart, and then on which JVM?

Naturally it is a requirement, JetBrains and Google only care about the JVM as means to launch their Kotlin platform, pity that they aren't into making a KVM to show Kotlin greatness.

If it feels salty, I would have appreciated if Android team was honest about Java vs Kotlin, but they weren't and still aren't.

If they were, both languages would be supported and compete on merit, instead of sniffling one to push their own horse.

Even on their Podcast they reveal complete lack of knowledge where Java stands.

replies(1): >>46185412 #
hunterpayne ◴[] No.46185412{5}[source]
Maybe the JVM team should listen to the market then and disable the jigsaw encapsulation that keeps devs on 1.8. Forcing a questionable security framework on everyone is why 1.8 is still used. Again, this is a problem because the PMs (and some devs) refuse to listen to what the market wants. So they are stuck keeping a 20 year old version of the code working. Serves them right to have to do this. It is their penance for being too arrogant to listen to the market.

PS Yes, I know, there is some weird way to disable it. Somehow that way changes every version and is about as non-intuitive as possible. And trying to actually support the encapsulation is by a wide margin more work than it is worth.

replies(4): >>46185701 #>>46185793 #>>46186548 #>>46191035 #
clhodapp ◴[] No.46186548{6}[source]
I'm pretty sure that the majority of shops that aren't worrying about Android have moved on from Java 8. The JVM team only keep Java 8 working for customers paying them lots of money for extended support contracts. And that's only because they have this long-term extended support system for all LTS JVM releases (they are also still supporting 11 in a similar manner).

On the other hand, Android doesn't even support Java 8. It supports the long-dead Java 7 plus a subset of Java 8 features. Android essentially froze their core application runtime in amber over ten years ago and have just been adding layer upon layer of compiler-level sugar ever since. The effect is an increasing loss of the benefit of being on the Java platform, in terms of code sharing.

replies(1): >>46188559 #
geokon ◴[] No.46188559{7}[source]
Didn't Google win the lawsuit with Oracle?

I never understood why they do not track the OpenJDK versions. I don't work on Android apps.. but it seems mildly insane to basically have a weird almost-Java where you aren't even sure if you can use a given Java lib.

Ex: I just took a look at a dependency I'm using

https://github.com/locationtech/spatial4j

Can it be used on Android..? I have no idea

From what I understand it's a weird stack now where nobody is actually writing Java for Android.

I'm still waiting for the day I can write a Clojure app for my phone..

(and not a Dart chat app.. but something actually performant that uses the hardware to the full extent)

replies(1): >>46188901 #
refulgentis ◴[] No.46188901{8}[source]
> I never understood why they do not track the OpenJDK versions. I don't work on Android apps.. but it seems mildly insane to basically have a weird almost-Java where you aren't even sure if you can use a given Java lib.

NIH syndrome

> (and not a Dart chat app.. but something actually performant that uses the hardware to the full extent)

I used to work on Android, quit two years ago and have used Flutter since, it's a breath of fresh air. It does use the hardware to the full extent, imo it's significantly more performant: it does an end-around all the ossified Android nonsense.

replies(2): >>46189029 #>>46190699 #
1. geokon ◴[] No.46189029{9}[source]
Hmm, so if you wanted to make an AR app, or some audio processing app, would you do that in Flutter? All the projects I have in mind involve using the camera/microphone/gps etc. Looking at Dart sample projects it just seemed to be quite different from what they're aiming at
replies(1): >>46195498 #
2. refulgentis ◴[] No.46195498[source]
My caffeinated instinct is to say basically "yes I'd do anything in Flutter", I honestly would rather stop coding than go back to anything I've done before (ObjC/Swift/Java/Kotlin with side journeys in C++). It boggles my mind how much of a different job dev is with true hot reload.

More carefully, and dealing with what you're indicating more directly:

There's stuff that we just need every millisecond of performance from.

Generally, Dart's great, I don't notice any difference between iOS / Android standard UI platforms.

But...for example, Flutter's image decoding is actually using "native" code behind the scenes, i.e. calling into C or OS-level APIs or browser APIs as needed on each platform. And there's a Flutter package called "image" that's Dart-native but I abhor because I know it's going to be higher latency than going thru lower-level code. (now I'm wondering how Java does this...I wonder if its JNI...)

Let's do a scenario: I've been contracted to build a bus route app for the local gov't. They want an AR feature. What happens if I choose to build on Flutter, build out the basic features, then get to the AR, and I'm getting 5 fps?"

Solution to that is "plugins" - https://docs.flutter.dev/packages-and-plugins/developing-pac... - the intro to the doc is way out of date, like years. TL;DR is you can drop in C / Swift / Java / whatever easily as needed.

You can get a sense of what that looks like from my package for doing ML inference here: https://github.com/Telosnex/fonnx, specifically https://github.com/Telosnex/fonnx/tree/main/lib/models/minis...: X_native.dart shows us calling into shared C code on every non-mobile platform. On mobile, I have to take a dep on specific packaged & code signed libraries provided by Microsoft for ONNX. Then, I (AI, at this point) writes Swift and Kotlin to call into that library. (Swift: https://github.com/Telosnex/fonnx/blob/main/ios/Classes/OrtM..., Kotlin: https://github.com/Telosnex/fonnx/blob/main/android/src/main...)

This might feel convoluted at first, it did to me, but really, all that's going on is: when things are slow, we write a Dart interface, then for each platform where we want to use native code, provide impls of that interface in native.