IDEA in Kotlin - Performance Native vs JVM

What if IDEA was 100% Kotlin and was distributed as native instead of JVM?

Can we dream of such things? :slight_smile:

2 Likes

What would be the advantage of that? It would do is break all of the plugins that are written in java. Also kotlin native is many times slower than kotlin jvm so this would slow down the ide even more.
Not to mention that it would take some serious effort to port all the required functionality to kotlin native.

2 Likes

Is kotlin native slower? Why is that?

My musing is exactly because of that, I personally don’t find idea to be either very fast or stable. It’s feature rich but I fight with the environment every day despite having a fast computer with a lot of RAM dedicated to idea.
JB is incredibly agile compared to Microsoft, but I find VS to be both faster and more stable, and I imagine that to be at least in part because it’s c/c++. VS is just worse in every other way so I prefer idea…
I didn’t mean to start a serious discussion, but now I’m curious why kotlin native isn’t faster, wouldn’t it be closer to the metal so to speak?

  1. not released yet, JB still working on performance
  2. lack of PGO
  3. KN memory management - sacrifice throughput for low mem footprint (KN also target embedded systems)
2 Likes

Makes sense. In theory could it be much faster than Java someday?

My work using Kotlin is for multi-platform projects, so KN does interest me for long term vision. I’ve just never been very impressed with Java performance. Even compared to JavaScript in Chrome, Chrome + JS outperforms Java for small things, has a faster warmup time, etc, Java just scales a lot better.
Also curious how fast Kotlin to WASM compares to plain JS :slight_smile:

Native applications are slower than jvm not only on kotlin-native, but in general on complicated software because of aggressive JIT optimizations. Moreover, open-world JVM applications allow the level of modularity, which is mostly impossible to achieve with native applications.

4 Likes

It seems that you’ve never measured Java performance. Or done it 15 years ago. The only more or less correct statement is about warm-up time, which is improved a lot in last years and actually different on different implementations of JVM. In general, JVM warm-up time is about second or less, which is not relevant for IDE.

4 Likes

It seems that you’ve never measured Java performance. Or done it 15 years ago.

I’m not trying to get into a debate on a Saturday. I don’t think you have much context behind my assertions.

Anyway, I appreciate the information. I have little experience with native development so it’s interesting to hear you advocate so strongly for the JVM. I think the JVM is fine and good for my purposes, but in a saturday sky is the limit daydream, I’m curious if Kotlin Native will ever blow the JVM out of the water.
I don’t know how true it is that “in general native applications are slower than JVM”. Minecraft for example became much faster when it was ported to C++. I have never heard of a company choosing Java over native, “because it’s faster”. It’s always, because it’s portable, or because it’s easier.

I am doing performance-sensitive computations and, believe me, I know how to measure it. It is possible to write very fast and optimized code in C/C++. The problem is that it requires tremendous amount of work and expertise. If you take a large project developed by average programmers, JVM solution will be faster. I can rephrase my previous statement: a complicated (this is important!) JVM program in most cases will be much faster than C++ program unless you spend a lot of time making specific native optimizations.
Computer games are different thing entirely, because there you need low level hardware optimizations not possible with VM.
There are several key performance problems in Java/Kotlin. For example, boxing of primitives and generic specialization and Kotlin developers are working on them, but in general even now, Kotlin-JVM is good for high-performance computations. Memory consumption and start-up times are of course worse than in native compilations.

8 Likes

I think the best way to capture the difference is that in many cases you just can’t write really fast code in Java. That’s why, when it really, really, really has to be fast, it’s written in C, C++ or a newer alternative like Rust.

The reason for this is in the detailed design of those languages as compared to Java, and doesn’t really have to do with being run in a VM. C++, especially, has been very carefully designed through all of its years so that an expert developer can use all the cool abstractions and generics, while at the same time understanding how all that stuff will disappear during optimization and what the equivalent code in a low level language like C would look like.

Java just isn’t that kind of language. While casually written code will often/sometimes perform similarly in Java vs. C++, things like type erasure, boxing, reference types, null / bound checking, etc., mean that an expert just cannot write Java code that runs as fast as his C++.

Kotlin also just isn’t that kind of language, and for the same reason(s), it’s just not gonna be possible to write really fast code for most things in Kotlin. It really should, however, be possible for Kotlin “native” to perform similarly to Kotlin JVM. That would require a good garbage collector, though, which might not be considered entirely “native” to some.

Maybe the Golang runtime would make a better target for a “more native” Kotlin that also runs fast. I’m sure Google wouldn’t mind.

1 Like

I don’t agree, at least not in a server/desktop environment. I think it will be extremely hard for kotlin to get close to the optimization the JVM can do and I don’t think this should be the goal for kotlin native. I think (and based on what I read, the kotlin team kind of agrees) that K/N is mostly focused on embeded devices/mobile. That means that the goal should be as fast as possible while still being extremely resource efficient. This is where K/N will have an advantage over running a VM.
Obviously K/N still needs to become faster. I used MPP for last years advent of code and kotlin native was considerably slower compared to the JVM. While I don’t think it needs to be as fast it still needs to become somewhat competitive.

7 Likes

I think this is an interesting discussion so I edited the title so that people can find it (google included :wink:)

1 Like

Java just isn’t that kind of language. While casually written code will often/sometimes perform similarly in Java vs. C++, things like type erasure, boxing, reference types, null / bound checking, etc., mean that an expert just cannot write Java code that runs as fast as his C++.

It is not quite correct. While C++ allows some more low-level hardware optimizations, things like boxing could be avoided by the expert. It requires some careful thinking, but it is the same with C++. Type erasure is not a performance issue (C++ in general does not have runtime types at all). References and checks are significantly optimized by the JIT. Benchmarking different languages is thankless job, but even those tests shows only minimal speed-up of C++ generated code compared to JVM on small optimized tasks - the field where you can use all advantages of C++.

5 Likes

not true at all, JIT is only good if you warmup your program for a long time, by the time it warm up, you already notice the slow downs, not only that, but also suffer from long startup time and heavy ressource usage

i can also benchmark one use case and show great numbers by running the program 1 000 000 times, is that what happen in the real world? JIT programs are bad, high latency, and sluggish UX is what you get as a result

How long is your long? Did you actually do any benchmarks or startup time measurements? What does UX have to do with startup times? Mindless citing of “Java is slow” myth is really tiresome.

And yes, running one task 1e6 times is what actually happens in real world. Of course if you are running any real-life CPU-intensive task and not a toy example from your head.

3 Likes

As a comment on what OP said; I actually dreamt that perhaps one day most java libraries would be rewritten in kotlin, then you could also have all the great java libraries(like spring) in native; But for this to happen all the jvm functionalities should be implemented by kotlin-common or kotlin-native(which would be quite difficult I imagine especially java’s reflection).
As for the performance discussions I think @scellow and @darksnake are talking about different sorts of programs. It seems like @darksnake is talking about CPU-intensive tasks and @scellow is talking about (more or less) your everyday desktop applications.

The difference between java and c/c++ for me are mostly about java needing more memory and having GC overhead(Isn’t it possible for java to free the garbage like rust?) vs java having much less development cost. Mind that GC time is in some cases unacceptable, for example in games where people buy 144Hz displays over 60Hz(I mean every millisecond might matter).

Yet again, I urge you to test your assumptions and search for articles if you do not want to spend your time.Java requires more memory not because of GC - it is common misunderstanding. Yes, managed memory model usually costs you up to 20% more memory reservation (not allocation). Modern GC like ZGC or Shenondoah can reduce memory overhead even further and give back unused memory to the system. Java memory consumption comes mostly from three things:

  • Class-loader and JIT, which will take more or less the same amount independent on actual memory needed by the application (not quite, but let us not dig the details). This is the price of open-world and easy modularity. It is a problem for small application since this fixed amount is about 50 Mb.
  • Thread stack. Relevant only for old-style applications which spawn a thread for each small thing.
  • The fact that java data structures (like hash map) are optimized for CPU performance instead of memory consumption. I think it is a benefit.

GC pause in normal application does not exceed 0.1% of the time. In modern GC, the heap is modularized, so stop-the-world is not the problem for a desktop for a long time now. It is possible to write almost zero-allocation (and zero-GC) JVM applications, just look at kotlinx-io design. But it requires some expertise to do so, just like on Rust or C++.

As fr your thesis about desktop applications, it is not quite correct. The thing that is definitely worse in JVM is the startup time. It could be up to few seconds (a lot of time) of huge projects. If you do not write console utilities and this startup time does not bother you, you will have no problems with performance. If you want a comparison, run the comparison of a framework like JavaFX with something like QT. You will be surprised.

6 Likes

Searching for articles will turn up lots of stuff on both sides of the argument: A few head-to-head benchmarks where Java wins, many head-to-head benchmarks where C++ wins, and thousands of complaints about how the benchmarks are unfair to Java :slight_smile:

1 Like

Somehow, this thread starts with the mention of imaginary IDEA implemented in Kotlin/Native, but the following discussion never mentions one performance bottleneck crucial for all IDEs in general: GUI.

In my experience (mostly Java/Swing and C++/Qt), GUI developed in C++ runs much faster. I can only guess why, and a reasonable guess is that one can’t actually implement GUI in 100% Java because the underlying API calls are all in pure C. Not true for Android, for example, but certainly so for most mainstream desktop OS (Windows and Linux, not sure about Mac here). You can implement a very thin wrapper around native API, and you’ll be just a couple of stack frames away from OS. How thin and how many frames depends on how feature-rich and platform-agnostic you want your wrapper to be (Qt does a really good job here). And even if your wrapper is thick and complicated in general, you can still hunt down specific performance bottlenecks and optimize the crucial parts.

With Java, you have to go through interop calls, one way or another. I’m not really an expert on how it works, but I imagine some argument marshalling and memory fiddling here. Can’t possibly be ultra-fast, especially if the underlying architecture requires a lot of such calls (I’m talking mostly about event handling and painting).

I’m mostly guessing here, but one thing I’m sure of: pure computational (CPU-heavy) performance is totally irrelevant when it comes to most desktop applications. Who cares how efficient your computations are when your context menus and copy-pasting is painfully slow?

1 Like