So the claim that Java is slow is true. That's why so many people hate it. The fact that Java is fast is also true.
It's the rise of these languages that confuses me.
They somehow got away with the 'fast enough' argument whilst Java is constantly being compared to languages that are designed for fine tuning for the target architecture.
In my mind it is Java that is 'fast enough' and,with Java 8, very expressive. The continued success of these incredibly slow interpreted languages in enterprises where you need to buy servers feels like an anti-pattern.
It was easy to find benchmarks showing that Java was fast. But Java turned out to be slower in every situation we might consider using it.
Command-line applications were slower because the JVM took ages to start.
GUI applications were slower, apparently because Python would use C-implemented widgets while Java would do much of the drawing itself.
Web applications were slower without any good excuse as far as I could see, but something in the application server that was the mainstream way of doing things added more per-request overhead than starting a whole new Python interpreter via CGI.
CPU-intensive operations (I remember image resizing in particular) were slower because, again, you ended up comparing the JVM against a well-written C extension.
Java marketing was a disaster. Remember when it was going to be the replacement for browsers? It was not a great way to engender goodwill.
Random anecdote which led me to stop calling Java slow: I'll never forget the time I took a 3000ish line Python program which had been heavily performance tuned and thus completely impenetrable. I converted it to a dumbest-scheme-possible naive implementation in Java weighing in at roughly 100 lines , expecting that to be a first pass. It turned out that the Java implementation was many times faster so we called it good enough and moved on with life. Obviously YMMV and all of that
CherryPy fits nicely into this window of opportunity, but as soon as you have to go back to your boss and say "I think we need a bigger boat" someone should be asking questions about library and language choices, at the very least there should be a conversation about prototypes vs production architectures.
Similarly, Python and the dynamic languages are 'fast enough' because in the 90s the bottleneck was IO, not CPU. That is still true, but is becoming less true. SSDs rapidly closed that gap, and it looks like memristor storage could mean that non-volatile RAM is as large as SSD and as fast as DRAM is today.
The dynamic language decision to focus on single threaded performance is also smart, but that will stop being true when CPU have hundreds of cores, instead of 10s. Synchronized access to cache is 100x slower than regular access. So to see benefit for work loads other than the "embarrassingly parallel" with multi-core you need around 100 threads. The new competition in the CPU market might see the first 100 core die on the market in 5 years.
The trend towards 'serverless' could be even worse for dynamic/interpreted languages. Smaller slices of billing will show that the same service written in Java vs Python cost 5-10x less. That was harder to show when you had to pay for at least two servers for every deployed service, now it will be very clear to CFOs how much language choice affects their bottom line.
What this means is that the perceived difference in performance between Java and Python can only grow over the next 5-10 years. If Java continues to gross you out, I'd be looking to pad your resume with something like Clojure / Go / Rust. High productivity, high performance languages are here and their relevance is growing.
"A JVM does that???" by Cliff Click is a good introduction on what can go in the background.
C++ can always win!
JVM has hotspot? use profile guided optmization in C!
There is no escape!
1) Swing. I have no idea what this does on startup but it is bad. This is what killed most java GUI apps. A simple AWT or SWT app will pop open while a simple swing app will take a few seconds to get started
2) Jars on systems with virus scanners. Jars are just zip files. Many virus scanners will unzip and scan a zip on every open which leads to each jar being unziped at least 2 times and often more if the app has to load more things from the jar at a later time.
3) Spring. Really spring is just a bad idea all the way through and most of the reason people hate java is Spring. Huge XML configuration files instead of code? Spring (mostly annotations now). Stupid names like AbstractSingletonProxyFactoryBean? Spring. That aside, on startup Spring will auto generate classes which really slows things down. This could have been done during the last build but spring does it at each startup which is really slow. Spring Boot has helped with startup times but it is still slower.
After startup Spring continues to kill performance. The underling code is full of maps to control request lifecycle so instead of just calling a method it has to ask "who all is configured to do something at step PreParseRequestEncoding?" then again at ParseRequestEncoding, PostParseRequestEncoding, PrePareRequestBody, ParseRequestBody.... Not real names but the idea and number of steps is. Most of the time the answer is "nobody" but it has to ask for every step that might ever need something done.
Add on top of this JPA which is super easy but quickly breaks down to a lot of DB calls. JPA is great for people who don't want to learn SQL and simple CRUD apps but anything with any amount of data will quickly slow down to thousands of DB round trips.
I'd like to see some reallife-ish comparisons with Jooq
That's like saying Java is for people who don't want to learn C...or C is for people who don't want to learn assembly.
It's the right tool for the right job. If you use it for everything, it's no so good.
> Huge XML configuration files instead of code? Spring (mostly annotations now).
Spring 3, yes. Spring 4 and 5, no. XML has not been the blessed configuration approach for ~4 years.
> Stupid names like AbstractSingletonProxyFactoryBean? Spring.
Java is a language that has evolved enormously in expressiveness since Spring began, meaning heavyweight Go4 patterns were necessary early on to maintain a flexible substrate with a uniform interface serving very many use cases? Spring.
> That aside, on startup Spring will auto generate classes which really slows things down.
I believed this urban legend too.
Dave Syer, who is understandably interested in Spring criticism, has done more empirical investigation than anyone on this topic[0].
The tl;dr is that boot time is proportional to total classes loaded. That's all, that's it.
In-memory reflection operations are hilariously, stupidly, insanely faster than I/O. The JVM fetches and loads classes individually. So if you have a lot of classes, it takes a longer time to load.
The other thing to bear in mind is that Spring relies on this much less than it used to. As the language and JVM have evolved, so has Spring.
> The underling code is full of maps to control request lifecycle ... Not real names but the idea and number of steps is.
Are you talking about servlet filters? Because any web framework is going to have a few of these. Spring MVC adds a handful and all of them can be removed, replaced or added to. Spring Security adds a bunch and all of them can be removed, replaced or added to. But the defaults are chosen because of feedback, not just for the heck of it.
> Add on top of this JPA which is super easy but quickly breaks down to a lot of DB calls. JPA is great for people who don't want to learn SQL and simple CRUD apps but anything with any amount of data will quickly slow down to thousands of DB round trips.
In general, yes, I agree that JPA is a PITA. For a small to medium system I would try to avoid it where possible. For a sufficiently large codebase -- thousands of domain objects, dozens or hundreds of programmers -- it might be a necessary evil.
Mind you, if you want to see a world where the database goes from abused to outright mocked and ignored, pay a visit to Rails land. It drives me batty.
[0] https://github.com/dsyer/spring-boot-startup-bench, particularly https://github.com/dsyer/spring-boot-startup-bench/tree/mast...
The biggest issue I have with spring isn't performance but is the huge internal state that is the basis of Spring's DI.
After a few versions you end up with code that depends on bean named 'Abd" to preform a task, but in the next version is renamed to "Abc" which fixes the typo, but makes all the documentation off. And the 3 other classes that also needed that task still look for it under the name "Abd". And then the next major version replaces this entire module and the bean name is now "Xyz". To me this IS spring programming. Googling the DI names and trying them one by until you get the desired run time functionality.
I've had apps in production with unused beans defined (It only had 1 function that only throw an exception and was never called) but had to be defined or something would break. Multiple team members wasted some free time trying to locate the code that was requiring that bean but nobody could ever figure it out. At some point everybody gave up, it was easier to just let it be.
Most developers have little to no idea what is actually going on inside their spring apps (or even what half their dependencies are). When a struts like vulnerability comes along in the spring world it is going to be a massive PITA to fix. With how complex this all is I have little doubt that a vulnerability exist somewhere in there.
Which Spring Boot ameliorates by providing starter POMs. Curated, levelled, updated collections of dependencies for common cases. No need to play whack-a-dep with Maven or Gradle. No need to track 50 different dependencies yourself.
The thing is: I don't care how Spring does the magic. I care that I don't have to care.
I came to Spring and Java-for-real development relatively late -- by fluke I was on what is almost certainly the first Boot production app ever deployed, back in early 2014.
Later I got a chance to see the primordial world of Spring 3. I understand the residual hate.
One thing that I have noticed is that with all these annotation, the Java compiler is not doing much any more. Java has effectively became a dynamic language (as in an interpreted language) where errors are only visible at runtime when hitting some specific method.
Coupled with the really slow startup time (again, I talk about Spring Boot--I get a steady 10s vs 0.01s for Go, same functionality), it makes developing a simple CRUD a pain compared to both Go or Python/Ruby...
For Ruby I see RubyMine doing what amounts to a fulltext search. It's next to useless.
For startup time, see my notes on the JVM and the link to Dave Syer's notes.
There's also the devtools starter to ease the JVM reload pain. Which to me is by far the biggest suckiness of the thing.
Even ignoring filters, it seems to me that Spring brings a lot of overhead. Adding an annotation to a method sometimes means that would appear to be a direct call between two of your beans is in fact separated by 10 method calls on a stack trace. In many cases this is not an issue (expecially in "enterprise" applications), but it is clear to me that performance is not really one of the main concerns of spring developers.
I generally try to stay away from strong opinions and assume that when something has an opinion there may be a reason behind it, but in the case of Spring and Java, I have concluded that those not using or familiar with Spring are simply clueless jokers.
If you really believe that JPA means "you don't have to understand SQL", then you definitely don't know what you're doing.
As for Spring, I get so tired of reading lengthy critiques that boil down to:
1. "It uses XML! (or at least it did 10 years ago, when my personal experience with it was last up-to-date)"
2. "It has some classes with long names! Named after design patterns that I don't like!"
By all means, don't use Spring if you don't want to. But know that Spring is very modular, letting you include or exclude whatever you like, and the core is rather light. If you're not using at least some of it, then you're probably re-writing it... and doing a worse job than they did. Either way, stop ranting about it on web forums if your knowledge is from 2007.
Is "the server" the only place where code is run today? That is a sad image for privacy and user sovereignty. I certainly still run a lot of code on my local system, and I wish more people did the same.
I've heard the "you're probably re-writing it... and doing a worse job than they did" argument so many times, is this on the spring forums or something?
But these days, Java VMs are vastly better and Java is competing with languages like Python and Ruby. The way things are today, the assumption is that Java is faster than its competition.