If the entire problem domain space is written in a language it's dumb not to follow suit. Libraries that solve problems reduce your work to your own specific issues, rather than 'building an apple pie from scratch'.
Java is good right now because most problems have libraries to do what you want. Most formats have APIs.
It's not perfect in any area - the start-up time is a bit lame, you have to write 'anti-Java' to really get close to native performance. But it's quick to build in, the toolchain is solid, the dependency framework works better than all the alternatives. It's a 95% language that's been made development friendly.
(Golang somehow added versioning late and is 'Git+' at best, NPM unpublished stuff, C++ is hell, etc. Rust crates just doesn't have much but seems to have been built properly).
But if you're working in a new space (crypto, AI, cloud) then you should definitely look at what the state-of-the-art libraries are written in.
And you should think real hard before you implement your app in anything else. Because there will be a real, long term, painful penalty unless you get VERY lucky and the entire ecosystem pivots to your language.
I’m also a long time java spring developer. I started writing a game recently and was really surprised about how bad the performance can be when you run it in a tight game loop.
The startup time is also a real problem, as you really want to be able to scale up pods quickly.
That said, it’s good enough right now. You can make it work at scale, and it’s worth the cost trade off of trying to do it more efficiently in a different language.
I would be curious to see how a rust microservice would compare in my companies infrastructure. How much cloud saving could we squeeze?
Writing high performance Java is definitely a bit of a dark science, a lot of the performance isn't just the code loop you're looking at, but memory allocations matter quite a lot as well. Complex hierarchies of large long lived objects can absolutely tank your performance.
There can also be a lot of performance to be gained by going off heap. I'd be probably be looking at an ECS design around MemorySegments, rather than modelling the game state with Java objects. Though, to be fair, this is how you'd write a game engine in C++ as well.
Spring Boot startup time is indeed a problem, especially when scaling horizontally on low cpu nodes.
If your environment allows for burst cpu usage until ready to accept traffic, you can start up really fast as spring does so much reflection magic during startup that can't be done during compilation "trivially". You can include hints for runtime configuration from a build, but it doesn't do much to help in really low cpu envs.
Then you can of course just do native images, but you lose some of the spring "magic", and might be annoying to refactor towards.
This actually makes me wonder if it is possible to preserve post-startup state and then restore it as a way to mitigate long computational stage during startup. I bet it is, maybe we could just serialize the application context and restore it.
> The startup time is also a real problem, as you really want to be able to scale up pods quickly.
I was learning a bit of spring last week and a spring boot web application, generated via the web interface boots in like 800msec:
...
Initializing Spring embedded WebApplicationContext
Root WebApplicationContext: initialization completed in 339 ms
Tomcat started on port 8080 (http) with context path '/'
Started DemoCourseApplication in 0.746 seconds (process running for 1.012)
...
Reusing my experience from other technologies... I'd say the issue might be in whatever you're doing in your initialization and/or how much stuff you're loading.
Looks like the core spring is decently fast, to me.
Could you expand on "how bad the performance can be" part?
If you are doing graphics, it is entirely more likely that you do something dumb there - there are many pitfalls.
Also, unless you are doing something very CPU-heavy, there won't be any noticeable difference as web servers are doing IO predominantly. Maybe slightly less RAM usage (but you could also just decrease the heapsize to tradeoff a bit of CPU-time for memory, if it were to make sense).
In my game loop I was using optional. When I profiled it the use of optional was one of the slowest points that could be optimized using null checks and ifs.
There were a lot of other slow areas as well, not where you would expect it.
Sure, Optional is not the most optimal thing to use/do, though depending on how many entities you were operating with, that itself may still be negligible.
That's not my experience, though game development is certainly a niche and Java may not be the top choice for that.
You might sometimes have to reach for SoA-like structures and reference them via indices, at least for the core ECS, but for the rest you can easily use bog-standard Java -- not everything has to be "ultra-fast, specially written java", just certain hot loops.
Right. I didn’t started digging into it until I realized the application was clearly sluggish in certain scenarios. As I am doing this for fun I am going to see what kind of speed up I get in rust for this.
Cold latency is an issue with microservices. If you need to use Java, you'll likely end up using frameworks like Spring or Quarkus, which somewhat diminish the advantages of using the JVM and Java as a language.
At that point, you might as well start with Go from the beginning.
Stackoverflow famously ran on a single, although quite beefy server PC for a long time (not any longer, but not for performance reasons AFAIK).
I think it's a good data point to have to scale your workload to stackoverflow's, and reconsider the hardware costs.
(Obviously horizontal scaling has its place, but if it's that variably scalable, maybe there are better solutions, e.g. a single bigger instance -- often times even for cheaper)
Double agree. If Java was the right choice 10-15 years ago for cheap enterprise apps, then certainly NodeJS is the way to go today. There are heaps of cheap developers and the ecosystem is ginormous.
I made the switch to Kotlin around 2018; after having been using Java since 1995. Java is a choice these days, not a necessity. Kotlin is a drop in replacement for Java in 100% of it's core use cases. No exceptions that I know of. Doesn't matter whether you do Android or Spring Boot. It kind of does it all. And it's actually really good at dealing with creaky old Java APIs. Extension functions (one of the party tricks modern Java hasn't yet picked up from Kotlin) are amazing for adapting old code to be a bit less tedious to deal with.
You don't really lose anything (APIs, tools, etc.); but you gain a lot. I still use Spring. But I've now used it longer with Kotlin than with Java.
And the nice thing with Kotlin is that it is gaining momentum as its own ecosystem. I'm increasingly biased to not touching old school Java libraries. Those lock me into the JVM and I like having the option of running things in wasm, in the browser or on mobile. Our frontend is kotlin-js and it runs a lot of the same code we run in our Spring Boot server. Kotlin multi platform is nice. I've published several libraries on Github that compile for platforms that I don't even have access to. Supposedly my kt-search client (for opensearch and elasticsearch) should work on an Apple watch. I've not gotten around to testing that just yet and I don't see why you'd want that. But it definitely builds for it. I had one person some time ago trying it out on IOS; same thing (I'm an Android user).
Ecosystems are important. But it's also important to not get too hung up on them. I say that as somebody that made the bet on Java when there was essentially no such thing as a Java ecosystem. It was all new. Kind of slow and wonky. And there were a lot of things that didn't quite work right. But it had lots of people working on fixing all of those things. And that's why it's so dominant now. People are more important than the status quo.
Sometimes you just have to cut loose from the past and not go with something safe but very boring like Delphi, Visual Basic, Perl, and several other things that were quite popular at the time and didn't quite make it. They're still around and there's a half decent library ecosystem even probably. But let's just say none of those things are obvious things to pick for somebody doing something new that was born this century.
Go as an ecosystem is definitely large enough at this point that I would label it as low risk. Same with Rust. Neither is going anywhere and there are plenty of well motivated people working on keeping all that going. Same with Java. All valid reasons for using any of those. But nothing is set in stone in this industry. A lot of things people were using in the nineties did not age well. And it will be the same in another 30 years. Most of those old people that will never change retire at some point. Java projects are pretty depressing to work on these days for me. Lots of grumpy old people my age. I've had a few of those in the last few years. Not my idea of fun. The language is one thing but the people haven't aged well.
I never had much experience with scala.js. The nice thing with kotlin-js is that it's just kotlin. Thanks to Android, it's actually a good fit for UI development and a lot of the same libraries work in a browser as well. For example, we use koin for dependency injection, kotlinx serialization, ktor-client, coroutines, and a bunch of other stuff. We also use some npms. Stuff like maplibre and tailwind for example.
As for the compiled code. I spend about as much time looking at generated js as I do examining jvm byte code (none in case you were wondering). It's a compilation target. Yes it's ugly. But who cares? It actually goes through a mininification/uglification step as part of the webpack build. So, yes, it's going to be ugly.
If the entire problem domain space is written in a language it's dumb not to follow suit. Libraries that solve problems reduce your work to your own specific issues, rather than 'building an apple pie from scratch'.
Java is good right now because most problems have libraries to do what you want. Most formats have APIs.
It's not perfect in any area - the start-up time is a bit lame, you have to write 'anti-Java' to really get close to native performance. But it's quick to build in, the toolchain is solid, the dependency framework works better than all the alternatives. It's a 95% language that's been made development friendly.
(Golang somehow added versioning late and is 'Git+' at best, NPM unpublished stuff, C++ is hell, etc. Rust crates just doesn't have much but seems to have been built properly).
But if you're working in a new space (crypto, AI, cloud) then you should definitely look at what the state-of-the-art libraries are written in.
And you should think real hard before you implement your app in anything else. Because there will be a real, long term, painful penalty unless you get VERY lucky and the entire ecosystem pivots to your language.