Java is fast, code might not be
siegers
192 points
198 comments
March 20, 2026
Related Discussions
Found 5 related stories in 33.2ms across 3,471 title embeddings via pgvector HNSW
- If you thought code writing speed was your problem you have bigger problems mooreds · 306 pts · March 17, 2026 · 61% similar
- JSSE: A JavaScript Engine Built by an Agent tilt · 26 pts · March 31, 2026 · 48% similar
- JavaScript Is Enough arbayi · 20 pts · March 22, 2026 · 48% similar
- Codegen is not productivity donutshop · 74 pts · March 15, 2026 · 48% similar
- Java 26 is here mfiguiere · 218 pts · March 17, 2026 · 47% similar
Discussion Highlights (20 comments)
koakuma-chan
As much as I love Java, everybody should just be using Rust. That way you are actually in control, know what's going on, etc. Another reason specifically against Java is that the tooling, both Maven and Gradle, still stucks.
bearjaws
JavaScript can be fast too, it's just the ecosystem and decisions devs make that slow it down. Same for Java, I have yet to in my entire career see enterprise Java be performant and not memory intensive. At the end of the day, if you care about performance at the app layer, you will use a language better suited to that.
kyrra
First request latency also can really suck in Java before hotpathed code gets through the C2 compiler. You can warm up hotpaths by running that code during startup, but it's really annoying having to do that. Using C++, Go, or Rust gets you around that problem without having to jump through the hoops of code path warmup. I wish Java had a proper compiler.
tripple6
Do good, don't do bad. Okay.
liampulles
Understanding algorithmic complexity (in particular, avoiding rework in loops), is useful in any language, and is sage advice. In practice though, for most enterprise web services, a lot of real world performance comes down to how efficiently you are calling external services (including the database). Just converting a loop of queries into bulk ones can help loads (and then tweaking the query to make good use of indexes, doing upserts, removing unneeded data, etc.) I'm hopeful that improvements in LLMs mean we can ditch ORMs (under the guise that they are quicker to write queries and the inbetween mapping code with) and instead make good use of SQL to harness the powers that modern databases provide.
jandrewrogers
You can write many of the bad examples in the article in any language. It is just far more common to see them in Java code than some other languages. Java is only fast-ish even on its best day. The more typical performance is much worse because the culture around the language usually doesn't consider performance or efficiency to be a priority. Historically it was even a bit hostile to it.
comrade1234
Also finding the right garbage collector and settings that works best for your project can help a lot.
zvqcMMV6Zcr
> Exceptions for Control Flow This one is so prevalent that JVM has an optimization where it gives up on filling stack for exception, if it was thrown over and over in exact same place.
wood_spirit
A subject close to my heart, I write a lot of heavily optimised code including a lot of hot data pipelines in Java. And aside from algorithms, it usually comes down to avoiding memory allocations. I have my go-to zero-alloc grpc and parquet and json and time libs etc and they make everything fast. It’s mostly how idiomatic Java uses objects for everything that makes it slow overall. But eventually after making a JVM app that keeps data in something like data frames etc and feels a long way from J2EE beans you can finally bump up against the limits that only c/c++/rust/etc can get you past.
taspeotis
Knock Knock Who’s there? long pause Java
victor106
this is great, so practical!!! any other resources like this?
titzer
For fillInStackTrace, another trick is to define your own Exception subclass and override the method to be empty. I learned this trick 15+ years ago. It doesn't excuse the "use exceptions for control flow" anti-pattern, but it is a quick patch.
hiyer
I ran into 5 and 7 in a Flink app recently - was parsing a timestamp as a number first and then falling back to iso8601 string, which is what it was. The flamegraph showed 10% for the exception handling bit. While fixing that, also found repeated creation of datetimeformatter. Both were not in loops, but both were being done for every event, for 10s of 1000s of events every second.
cmovq
When you're using a programming language that naturally steers you to write slow code you can't only blame the programmer. I was listening to someone say they write fast code in Java by avoiding allocations with a PoolAllocator that would "cache" small objects with poolAllocator.alloc(), poolAllocator.release(). So just manual memory management with extra steps. At that point why not use a better language for the task?
ww520
The autoboxing in a loop case can be handled by the compiler.
kpw94
The Autoboxing example imo is a case of "Java isn't so fast". Why can't this be optimized behind the scenes by the compiler ? Rest of advice is great: things compilers can't really catch but a good code reviewer should point out.
cogman10
Nitpick just because. Orders by hour could be made faster. The issue with it is it's using a map when an array works both faster and just fine. On top of that, the map boxes the "hour" which is undesirable. This is how I'd write it long[] ordersByHour = new long[24]; var deafultTimezone = ZoneId.systemDefault(); for (Order order : orders) { int hour = order.timestamp().atZone(deafultTimezone).getHour(); ordersByHour[hour]++; } If you know the bound of an array, it's not large, and you are directly indexing in it, you really can't do any better performance wise. It's also not less readable, just less familiar as Java devs don't tend to use arrays that much.
jerf
Any non-trivial program that has never had an optimizer run on it has a minimal-effort 50+% speedup in it.
Okx
The code: public int parseOrDefault(String value, int defaultValue) { if (value == null || value.isBlank()) return defaultValue; for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); if (i == 0 && c == '-') continue; if (!Character.isDigit(c)) return defaultValue; } return Integer.parseInt(value); } Is probably worse than Integer.parseInt alone, since it can still throw NumberFormatExceptions for values that overflow (which is no longer handled!). Would maybe fix that. Unfortunately this is a major flaw in the Java standard library; parsing numbers shouldn't throw expensive exceptions.
spankalee
Avoiding Java's string footguns is an interesting problem in programming languages design. The String.format() problem is most immediately a bad compiler and bad implementation, IMO. It's not difficult to special-case literal strings as the first argument, do parsing at compile time, and pass in a structured representation. The method could also do runtime caching. Even a very small LRU cache would fix a lot of common cases. At the very least they should let you make a formatter from a specific format string and reuse it, like you can with regexes, to explicitly opt into better performance. But ultimately the string templates proposal should come back and fix this at the language level. Better syntax and guaranteed compile-time construction of the template. The language should help the developer do the fast thing. String concatenation is a little trickier. In a JIT'ed language you have a lot of options for making a hierarchy of string implementations that optimize different usage patterns, and still be fast - and what you really want for concatenation is a RopeString, like JS VMs have, that simply references the other strings. The issue is that you don't want virtual calls for hot-path string method calls. Java chose a single final class so all calls are direct. But they should have been able to have a very small sealed class hierarchy where most methods are final and directly callable, and the virtual methods for accessing storage are devirtualized in optimized methods that only ever see one or two classes through a call site. To me, that's a small complexity cost to make common string patterns fast, instead of requiring StringBuilder.