IDEA in Kotlin - Performance Native vs JVM

Again, you should test it. Qt and JavaFX give more or less the same performance. I believe JavaFX will be even significantly faster in some cases. In fact inside structure of both frameworks is quite similar. All legends about “slow Java” and “slow Java GUI” come from old AWT implementations, which were slow indeed and long time obsolete by now.

As for IDE, the main performance bottleneck is definitely not the GUI. Graphics takes only a tiny fraction of CPU time in this case. Project indexing is much more demanding.

2 Likes

Fair enough. I’m comparing Swing with Qt, maybe with JavaFX it’s better. But IDEA is implemented in Swing, right?

And while it’s true that IDE does a lot of things, it’s GUI where performance affects UX the most. Who cares whether project indexing takes 10 or 30 seconds? Well, for really large projects (such as IDEA itself), it is important, but in most cases the user struggles with GUI performance. 0.1s vs 0.2s “Page Down” scroll is much more important than 10s vs 30s project indexing. I was recently refactoring one God-class application of 6000 lines into smaller units, and the editor performance was a bit less than satisfactory until I managed to get every unit below 2000 lines. But of course it is quite possible that it’s not Java’s (or Swing’s) fault at all. It’s just that whenever I see a program developed in Java, I always (and I mean always) see a sluggish GUI, as opposed to most C++ programs. It could be due to a variety of reasons, though…

Boxing OR type erasure can be either optimized. But with boxing AND type erasure, optimization become a lot more challenge because it’s hard to optimize boxing if types are erased. Just compare the performance difference between Array<Int> and IntArray, which only the previous one can be used generically due to type erasure.

Even though I think this discussion is fascinating it is going nowhere. I think we heared arguments for both C/C++ is faster and JVM is faster. In the end it doesn’t really matter unless we have any real numbers to show.

One place to start looking is this wikipedia article (yes I know wikipedia, look through the references there is some good stuff there)

A nice article from 2003 compiling a list of benchmarks and giving some more reasons why java isn’t t slower than C/C++.
http://www.scribblethink.org/Computer/javaCbenchmark.html
And this article is from 2003. I argue that java performance will have increased more than C/C++ performance since then, because there are more possible improvements in systems like JIT and GC compared to plain C/C++ optimizations.

Type erasure does not have anything to do with Boxing. Boxing is optimized in compile time or during JIT optimization. Knowing your type in runtime won’t help you. It is possible to replace Array<Int> by IntArray in some cases during code generation. Kotlin team is working on it. There are also several issues on tracker to implement compile-time unboxing. We can discuss it in another thread or in slack. Boxing is a major problem for things like performance-sensitive computations, but it is not a problem for IDE.

another proof for the delusional people

recently jetbrains ported the toolbox app from c++ (native) to kotlin (JVM): https://blog.jetbrains.com/blog/2020/04/23/toolbox-app-1-17-rewritten-in-kotlin/

result:

from 60mb memory usage to 300mb, with an increase of startup time and CPU usage

So real world scenario, for desktop applications, JVM is BAD

I’m interested how you come to that conclusion based on this. Firstly let me say that I can’t confirm the higher CPU usage (I didn’t run any real tests, but I didn’t see any real CPU usage before and I don’t set see any now). As for the memory usage and startup time, I belive you. I don’t know the previous memory usage but the 300mb matches with what I see.

That all matches pretty much with what people are saying about the JVM though. The JVM has an initial cost in required memory size and startup time but after that will perform as fast or faster than a native program. I’m prepared to belive that the size increase from 60mb to 300mb is due to the switch from C++ to kotlin (including extra libraries and the jvm).

So what does that mean? Well, the toolbox app is a background application that takes nearly no CPU to run (at least I can’t see any real CPU usage on my mac or my PC) so performance cant be much worse than before. It could be better or worse but I can’t tell.
Yes memory usage is up and this is definetly a downside and might be a problem for some older computers but shouldn’t really be too big of a concern, but C++ was better here.
Startup time doesn’t matter for this tool at all. It’s something that runs in the background and starts up when you start your computer. It might slightly slow down your computer startup, but if this is a big concern you shouldn’t be using background tools like this anyways.
All in all I consier those downsides quite small. The increased memory footprint is probably mostly due to the JVM and therefor not relevant for bigger applications and the other downsideds are not noticeable at all.
So what are the upsides? Well, there are a few listed in the article you linked: increased productivity from switching to kotlin, easier code sharing between different JetBrains tools, etc.
Also they mentioned thinking about switching to kotlin native in the future, which would reduce the memory size again, but using Kotlin JVM is a good step in getting there while already gaining the advantages.

I’m not sure that I would classify the toolbox app as a typical desktop application so your conclusion is only partially right in the best case. I doubt the size difference would be noticeable for a program like IntelliJ. Startup time is an issue but I think everyone here acknowledges that native is better for that compared to the JVM. As s for the CPU usage I don’t see any difference and there isn’t any mention of it anywhere in your link (not in the article and not in the comments).

This kind of mindset is what makes desktop applications horrible to use. We are now discussing whether going from 60 to 300 MB is bad or acceptable. But if you think about it, isn’t using 60 MB to manage a list of dozens of applications already something to be ashamed of?

I have PostgreSQL 11 with the default settings running on my Windows machine. It manages almost no data. With a quick count I find 20 processes (including 1 conhost.exe) related to it. Total working set? Less than 200 MB. I might be wrong, but somehow I feel that a bit of graphics for a desktop app cannot possibly consume more memory than an enormously complex piece of software.

Old guy talking here: I once had 16 MB for the operating system, Visual C++ and a couple of other programs I had open. Yes, it was terribly slow for some operations, but other things worked smoother than they do know. And it did provide thousands more features than the Toolbox.

If anyone knows JVM switches that shave off a large percentage of the memory usage in exchange for slightly reduced performance, I would be interested.

Now if the Toolbox would have a CLI, I would not mind if it used 750 MB :wink:

2 Likes

To o be honest I agree with you, mostly. 60mb is a lot for a small application like the toolbox and 300mb is definelty much more than necessary. Applications nowadays contain a lot of unnecessary stuff that comes as part of libraries or the jvm and this is definitley a problem. Less for applications but looking at the web it’s absurde how big some simple websites are.

That said, we have a lot more memory now and I think that gaining programming productivity for memory usage is a good trade in many cases. Also my argument wasn’t just targeted at this specific program. I was arguing that the 240mb from switching to the jvm is a small price for normal(bigger) desktop applications. I still agree that we should find a way to reduce unnecessary bloat in the future. Making the JVM more modular to reduce the minimum size required or investing into technologies like kotlin native is a good way to do that, but I don’t think kotlin native is quite there yet or the best tool for something like IntelliJ. The JetBrain toolbox on the ohter hand could probably benefit much from switching to native (once kotlin native is a bit faster).

1 Like

I would be interested in seeing the memory usage of the new toobox on a modern JVM with Shenandoah GC, which allowed me to reduce some services memory footprint from 300Mo down to 90 in the past.

the JVM developers really worked on memory usage and startup times , and benchmarking with JVM 8 is for me irrelevant

As Wasabi375 suggests, scellow’s example doesn’t necessarily prove anything. Even if the app was a ground-up rewrite, it’s still likely to use approaches from the C++ version that aren’t necessarily well suited to Java. And in practice, it’s also likely to be influenced by the C++ version’s data structures, organisation, algorithms, library, &c. All of which make it a slightly unfair comparison.

I’d be interested to see the performance of a C++ app which had been converted from Java; I wouldn’t expect to see a comparable saving. (Possibly none at all.)

(As the old saying goes, the determined programmer can write FORTRAN programs in any language!)

You mean because those guys at JetBrains don’t know how to write efficient Java code? In my experience they do pretty well.

You also need to remember that JVM does not actually use all the memory it says it uses. Usually it is just virtual memory allocation, which does not cost anything. When I did those measurements of actual memory allocation rates, I found it hard to find how much memory is actually used. Especially on linux.

It is hard on all systems. This is on Windows in Process Explorer (using Dutch number notation):

You have to look at the working set, BUT part of this is shared between processes: WS Shared. How much of that memory you can ascribe to a particular process depends on between how many processes things are shared.

The total amount of memory that this process can share is under WS Shareable. Substract WS Shared from this and you get the amount that is only used by this process.

The last column: WS Private, shows the amount of memory that really belongs to the process and is currently in main memory.

WS Private + WS Shareable = (approximately) Working Set.

So this JVM uses somewhere between 177,496 (WS Private + WS Shareable - WS Shared) and 190,056 (WS Private + WS Shareable) K of main memory.

Private Bytes is the/some amount of allocated virtual memory, but this does not really say much.

4 Likes