8 ms·
I led our teams to switch from Java to Go because of the productivity of development, but then noticed deployment was simpler and faster, memory usage was slash
by martingxx 10y ago
I led our teams to switch from Java to Go because of the productivity of development, but then noticed deployment was simpler and faster, memory usage was slashed (for comparable applications), request/response times were much more consistent, startup was practically instant and as a result we started aggressively rewriting Java applications to Go and saw a notable difference in the number of machines we needed to run in AWS.
So in my situation, the JVM is heavier by every single measure listed, and for each by a considerable margin.
- lossolo 10y agoI don't know why you are getting downvoted for sharing your real world experience, lately "fanboyism" on HN is getting out of hand. I have similar experience with one of the services that was ported from Java to Go.
- brianwawok 10y ago> aggressively rewriting Java applications to Go and saw a notable difference in the number of machines we needed to run in AWS. This is the easy trap to fall into though. What if you aggressively rewrote the Java apps from crappy legacy frameworks to well developed Java apps? A rewrite ALMOST always is faster. So the new language seems faster. Except if you would then rewrite the rewrite back in the original language... you could even still be faster. Very hard to split apart what is faster because the rewrite got rid of lots of bloat, and what is faster because it is legit faster. Java is legit fast when it is written well. Also very easy to make a bloat fest.
- martingxx 10y agoThese apps are mostly microservices and the Java ones are mostly only a year or two old. None of them use things like spring. Some use Dropwizard. Would you consider dropwizard modern? If not, what would you use instead?
- brianwawok 10y agoA lot more to an app than MCV framework. I realize dropwizard tries to be the everything for the app, but at the core it is a MVC with some bundled libs.
- nostrademons 10y agoTake a look at the TechEmpower benchmarks: https://www.techempower.com/benchmarks/ https://www.techempower.com/benchmarks/ DropWizard is modern, but it isn't fast. Go and even Node.js are significantly faster. If you want performance, you cut layers out of the stack - check out the numbers for raw servlets or even just straight Jersey annotations in that benchmark. If I were doing JSON-over-HTTP microservices in Java, I'd likely use straight Jersey + Jackson, or if performance was really a problem, Boon over straight servlets. What framework did your Go rewrite use? The standard libs?
- sk5t 10y agoOn first glance the dropwizard test app appears to be doomed to mediocrity via reliance on hibernate. Call me crazy, but I like my dropwizard with Spring DI for (singleton) resource setup, a micro-ORM to get work done, and HikariCP datasources at runtime.
- imtringued 10y agoWhat's wrong with hibernate? The only thing I can think of is that you're not using "JOIN FETCH entity.relation" when accessing collections and end up with the N+1 select problem but that is because you're using any ORM incorrectly. Entity framework has include and active record has includes which do the same thing. The qt ORM also has something similar. The only ORM I have seen that lacks this critical feature is odb. It doesn't allow setting the fetching strategy on a per query basis. You have to either always use eager loading or lazy loading which basically makes it useless for my purposes.
- sk5t 10y agoWell, for benchmarking the essential framework, which does not mandate any ORM, I would want to use something for data access that takes the question of time spent on type reflection, internal caching, and the like, out of the picture. Hibernate and EMF have their place, but not as part of benchmarking the thing that hosts 'em. Core Dropwizard performance is all about how it uses Jetty, Jackson, and maps requests to resources and operations.
- fetbaffe 10y agoYes, the limitation is rarely the programming language, it is the programmer. Also, when you do the rewrite you have already solved the domain problem that you did not fully understand when implementing it the first time.
- hyperpallium 10y ago"Plan to throw one away; you will, anyhow." First version to understand the problem, second version to solve it. But deployment, gc pauses and startup time (jvm vs go) are orthogonal to program quality. I would also expect go to have less memory usage. > deployment was simpler and faster, memory usage was slashed..., request/response times were much more consistent, startup was practically instant
- jpgvm 10y agoOrthogonal to quality but imperative to velocity. At the end of the day despite Go's failings it's a good (maybe the best?) language for large projects and teams because it compiles fast, is easy to anyone to run anywhere, tests run quickly, programs execute quickly and there is already good tooling/editor support. Nothing beats efficient workflow for improving velocity.
- fetbaffe 10y agoI could use the exact same arguments but for PHP.
- noir_lord 10y agoWhich is why I still often use PHP. For my usages its a reasonable language.
- jpgvm 10y agoNot quite, I omited here that it is also statically typed and is a future proof language. Mainly because these are properties already shared with Java. However this is not true of PHP. PHP is a great velocity language, provided you have a small(er) team or are willing to commit to additional controls on how you write your PHP (document types/structure of arguments mainly) to ensure that your PHP code is able to be read quickly by other developers. Personally I prefer Go here because it enforces good readability by default and therefore scales better with team size.
- hota_mazi 10y ago> This is the easy trap to fall into though. Indeed. It's a typical honeymoon phase with very little regards to 1-2-5 years in the future. The cost of having picked to Go will be fully apparent then.
- shard972 10y agoI really want to see a comparison of a language like go to something much more in the functional sphere when it comes to maintainability of a large codebase. I really feel like that one of the big issues we as programmers want to get a better handle on but there isn't a lot to go off that isn't based off opinions (which can be hard to validate).
- nvarsj 10y agoYou're still limited by the JVM technology, regardless of how you write your app - large heap, and big tail latencies (JVM's GC is designed to be throughput optimised, whereas golang is latency optimised).
- deleted 10y ago[deleted]
- dm3 10y agoActually, the new G1 collector deals very well with latency-sensitive workflows. I'd say it's comparable to Go if you adjust your heap size to the working set. You can try running the benchmarks here - https://gitlab.com/gasche/gc-latency-experiment https://gitlab.com/gasche/gc-latency-experiment.
- jerven 10y agoJust use one of the other JVM's that have GC that are latency optimised such as Zing from Azul, Metronome from IBM or OpenJDK with Shendoah from RedHat. The power of Java is that there is more than one JVM and that can really save you a lot of money/developer time if the world changes under your ass ;) i.e. had a JVM based graph database, ran it on Hotspot -> big GC pauses, moved to Zing no more pauses. All we needed to do is run a different VM and problem went away (new problem was of course that Zing costs but not much, also now with Shendoah coming for free we could probably have moved to that) With GO you can't do that yet. If your app is not latency, bound but throughput bound there is no place to switch too other that a rewrite. That flexibility of deployment on JVM tech gives us a lot insurance for no costs, until we need it.
- ldev 10y agoExactly, that's how some not very bright people were tricked into thinking that Node.js is actually fast.
- Zach_the_Lizard 10y agoAnd at work, we're now rewriting all those NodeJS services in Go or Java. We hired some Node maintainer(s) a long time ago, rumor has it, who got us on the Node train.
- kazagistar 10y agoHow do you do async in java? While it does have CompletableFutures now, none of the libraries (specifically databard drivers) seem to support it, so I always end up with a blocked thread per request.
- tynpeddler 10y agoJava has had non-blocking IO for some time. https://en.wikipedia.org/wiki/Non-blocking_I/O_(Java) https://en.wikipedia.org/wiki/Non-blocking_I/O_(Java) Unfortunately it seems difficult to use (to me at least), but frameworks like netty are build on top of it to provide incredible performance. However, the fact that Java provides real threading means that a blocking io is not a performance problem if you use the correct patterns.
- kasey_junk 10y agoI've spent a fair bit of time in both, most recently the last couple of years in go. I think its a very mixed bag and there is no clear winner. The tooling, especially for runtime operations, are so much superior to the golang options its night and day. I have much more success modeling complex business models in java with its better type system, and for doing low latency work its much easier to do on the jvm due to the availability of better libraries (which may get better in go) and the concurrency options are miles better on the jvm. Go's stack allocation and gc defaults make for easy management in most of my default cases. The ease of adding http endpoints to things is phenomenal. Being able to write easy cli applications in the same language I write daemons in is great. All told, I think for simple daemons and cli's I'd go golang, for more complex systems I'd go jvm. I, personally, think the binary deployment thing is overblown. I've never had any problems deploying jvm applications and the automation to do either seems essentially the same to me. As for the relative "heaviness" I think golang definitely feels lighter, but that is largely because golang apps do less. Once you start having them do more they start to "feel" just as heavy as java apps (for whatever "feel" means). * [edit] called golang heavier meant lighter
- jshen 10y agoI have golang website/web app that runs at tens of megabytes per process. A very similar java web app runs in a few hundred megabytes per process. I also run these in on cloud platforms that auto scale. The golang processes spin up very quickly, the java ones not so much. In these two respects the JVM is heavy compared to golang for my very common scenarios. The heaviness also causes me to spend more money for the JVM solution.
- mike_hearn 10y agoBut what max heap size did you set for the JVM? I have an app that people were complaining took too much memory. A quick look with VisualVM showed that its actual heap usage when idling was only 50 mb but because we hadn't set any heap size limit, it was reserving hundreds of megs from the OS. The idea is that it can run faster if it does that. The fix was simply to use the -Xmx option to tell it to use less memory and GC more often.
- kodablah 10y agoAs another commenter mentioned, I think this is much more the programmer and less the language. Sure, the language may recommend certain approaches which carry across teams differently, but it still often comes down to the app, not the language. I implemented a rudimentary Java AOT targetting Go and the trimmed-down stdlib grew so big Go took hours compiling it (granted some of that is how I approached OOP and what not).
- geodel 10y ago> I implemented a rudimentary Java AOT targetting Go and the trimmed-down stdlib grew so big Go took hours compiling it Have you reported to Go devs? Sounds interested use case.
- kodablah 10y agoYes[0] though I think the issue title is a bit off. They did bring it down from over 7 hours to 30 minutes ish in a recent release, but it's still is too long, too much CPU, and too much mem. They are very reactive of course which is something I can never say about OpenJDK. 0 - https://github.com/golang/go/issues/18602 https://github.com/golang/go/issues/18602
- andrewvc 10y agoThese sorts of comments are (no offense) worse than useless. Benchmarking is one of the most difficult things to do in software, and anecdotes like this just make things confusing for new engineers and feed the perpetual hype train around newer languages. Please refrain from making statements like this unless you have a reproducible quantifiable analysis. If you really wanted to demonstrate the effect you describe you'd need to have the same team rewrite the application twice, once Java->Java, once Java->go, making sure to align the program structure as much as possible (making exceptions to take advantage of lang specific features of course). If you were to do that, then that would be interesting! No one does that of course because it's expensive and wasteful from a business perspective, but it's the only way to determine anything useful.
- exabrial 10y agoThese types of arguments cause many intelligent people to headdesk. They're hardly an apples to apples comparison. Of course "Go was Faster". It's because you started with a clean slate!
- jshen 10y agoThat's not it. A fairly small http server in go will run in tens of megabytes. The same thing on the JVM requires a couple hundred megabytes at best. The difference in startup time is roughly the same as well.
- mike_hearn 10y agoAre you sure? I've written small HTTP servers in Java that can happily run with a heap of 30-50mb or less. Runtime overheads add some on top of that, but not much. I think the perception of Java suffers a lot because it will consume all the RAM on your machine by default if you let it (but not immediately). It's a very poor default because even though there are technical arguments for doing that (goes faster), they aren't well known and people tend to assume "more memory usage == worse design". There are a lot of myths about the JVM out there. We can see on this thread the idea that it takes 1.5 seconds to start being repeated multiple times, each time someone else points out that it's actually more like tens of milliseconds to start.
- mnw21cam 10y agoIt was a couple of seconds on my Cyrix 300MHz-ish CPU back in 1998. I would have expected it to get a little better since then.
- geodel 10y ago> it will consume all the RAM on your machine by default if you let it I wonder if Oracle documents are plain wrong for JDK 8 docs for maximum heap size[1]: "Smaller of 1/4th of the physical memory or 1GB. Before Java SE 5.0, the default maximum heap size was 64MB. You can override this default using the -Xmx command-line option. Also Oracle has chosen correct defaults because it took Java long time to shed its reputation of being dog slow and if they optimize for memory it will start looking worse in performance. 1. https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc...
- janwillemb 10y ago"Don't rewrite an application from scratch. There is absolutely no reason to believe that you are going to do a better job than you did the first time." -- Joel on Software, Things You Should Never Do, Part I [1] [1] https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/ https://www.joelonsoftware.com/2000/04/06/things-you-should-...
- tonyedgecombe 10y agoI do like that article but have ignored it several times for good reasons.
- pythonaut_16 10y agoI think a better interpretation of the title/article is "Don't assume that rewriting from scratch will fix all of your problems"
- e3b0c 10y agoWe have similar experiences as well. $ ps -eo rss,cmd,user | grep jenkins 4928228 /usr/bin/java -Djava.awt.he jenkins $ ps -eo rss,cmd,user | grep drone 12940 /drone agent root 19924 /drone server root We run the two applications in the same machine. Admittedly Jenkins is much feature-rich but we only use its vanilla settings without whatever fancy plugins for a few legacy SVN repos. P.S. The Drone server and agent are running within docker containers.
- klodolph 10y agoI wonder how much of this is due to a couple differences: in Go you can embed structures in others instead of using a pointer, strings are UTF-8, and arrays (slices) are resizeable by default. (I'm sure a chunk of the difference is due to a better understanding of the program during rewrites.)
- astrostl 10y ago> memory usage was slashed A lot of this has to do with another unmentioned, terrifically annoying property of the JVM: pre-launch min/max heap allocation. Standard operating procedure is to go with the default, and overbump it if your needs exceed it. I can't possibly imagine how many petabytes of memory are unnecessarily assigned to JVMs throughout the world as I type, apps consuming 79MB with a 256MB/512MB heap size.