Live data from Hacker News

Java is fast, code might not be

jvogel.me

81–90 of 259 posts

Re: Java is fast, code might not be

#81
post #26
post #10

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.

This is why I use java for long running processes, if i care about a small binary that launches fast, i just use something slower at runtime but faster at startup like python.

So long as you aren't in a docker container, The openjdk can do fast startup pretty trivially.

There are options to turn on which cause the JVM to save off and reload compiled classes. It pretty massively improves performance.

You can get even faster if you do that plus doing a jlink jvm. But that's more of a pain. The AOT cache is a lot simpler to do.

https://openjdk.org/jeps/514

Re: Java is fast, code might not be

#82
The code:

  public int parseOrDefault(String value, int defaultValue) {
      if (value == null || value.isBlank()) return defaultValue;
      for (int i = 0; i 
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.

Re: Java is fast, code might not be

#83

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 inde…

> external services (including the database)

Or even the local filesystem :)

CPU calls are cheap, memory is pretty cheap, disk is bad, spinning disk is very bad, network is 'good luck'.

You can O(pretty bad) most of the time as long as you stay within the right category of those.

Re: Java is fast, code might not be

#84

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…

Can you share the libs you 're using?

Re: Java is fast, code might not be

#85

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[…

maybe it would be a little better to use ints rather than longs, as Java lists can't be bigger than the int max value anyways. Saves you a cache line or two.

Re: Java is fast, code might not be

#86

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 inde…

Easy to get wrong as well. There's a balance with a DB. Doing 1 or 2 row queries 1000 times is obviously inefficient, but making a 1M row query can have it's own set of problems all the same (even if you need that 1M). It'll depend on the hardware, but you really want to make sure that anything you do with a DB allows for other instances of your application a chance to also interact with the DB. Nothing worse than fi…

ORMs are a caching layer for dev time.

They store up conserved programming time and then spend it all at once when you hit the edge case.

If you never hit the case, it's great. As soon as you do, it's all returned with interest :)

Re: Java is fast, code might not be

#87
post #85

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[…

maybe it would be a little better to use ints rather than longs, as Java lists can't be bigger than the int max value anyways. Saves you a cache line or two.

Fair point, but it is possible this isn't a list but rather some sort of iterable. Those can be boundless.

Practically speaking, that would be pretty unusual. I don't think I've ever seen that sort of construct in my day to day coding (which could realistically have more than 1B elements).

Re: Java is fast, code might not be

#88
post #74

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.

javac for better or worse is aggressively against doing optimizations to the point of producing the most ridiculously bad code. The belief tends to be that the JIT will do a better job fixing it if it has byte code that's as close as possible to the original code. But this only helps if a) the code ever gets JIT'd at all (rarely true for eg class initializers), and b) the JIT has the budget to do that optimization. Although JITs have the advantage of runtime information, they are also under immense pressure to produce any optimizations as fast as possible. So they rarely do the level of deep optimizations of an offline compiler.

Re: Java is fast, code might not be

#89
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.

Re: Java is fast, code might not be

#90
post #74

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.

Why should compiler optimize obviously dumb code? If developer wants to create billions of heap objects, compiler should respect him. Optimizing dumb code is what made C++ unbearable. When you write one code and compilers generates completely different code.

The problem is rather that Java doesn't have generics and structs, so you're kind of forced to box things or can't use collections.
Post reply on HN