DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Spring Microservice Tip: Abstracting the Database Hostname With Environment Variable
  • Mastering Thread-Local Variables in Java: Explanation and Issues
  • How To Verify Database Connection From a Spring Boot Application
  • Java EE 6 Pet Catalog with GlassFish and MySQL

Trending

  • Microsoft Azure Synapse Analytics: Scaling Hurdles and Limitations
  • Mastering Fluent Bit: Installing and Configuring Fluent Bit on Kubernetes (Part 3)
  • The Modern Data Stack Is Overrated — Here’s What Works
  • What Is Plagiarism? How to Avoid It and Cite Sources
  1. DZone
  2. Data Engineering
  3. Data
  4. Is Java Really Faster Than Go?

Is Java Really Faster Than Go?

Learning about performance differences between microservices written in Java and Go will help you plan the language you choose when building your own services.

By 
Kai Hendry user avatar
Kai Hendry
·
May. 05, 21 · Tutorial
Likes (23)
Comment
Save
Tweet
Share
20.3K Views

Join the DZone community and get the full member experience.

Join For Free

Researching Earlier Java/Go Benchmarks

Earlier I blogged that Go is better than Java, but it lacked evidence and datapoints. I wanted to start from some earlier work, to prove to my colleagues that Go is as fast as Java and quick to start up. Speed is critical for serverless since the process can be stopped when not in use and started again from cold to serve a request!

So after searching https://dzone.com/ for “Java Go” comparisons I was surprised to find a benchmark article by Ivan Nikitsenka (original author) at the top of results:

Which concluded that Java can serve twice as many simultaneous users as the Go application.

WHAT?

Is that true?! Can Java’s lazily just-in-time compiler be faster than a Go static binary?! Can I reproduce his results!?

Reproducing the Results

To the original author’s credit, he publishes the source of his Java and Golang application as well as how he tested with Jmeter, his results AND how to run it all on a neutral playing ground of AWS via Cloudformation!

I ran it locally on my T14s Thinkpad and indeed the Go application was erroring compared to the “springboot” Java app. Despite the bank-go image weighing in at 10.2MB compared to the 991MB image size of bank-java and consuming a lot less resources whilst running:

Java running with docker stats Go running with docker stats

Why Is Go Slower?

Instinctively I thought the database connection must be the bottle neck. The original author’s bank-go database functions use https://github.com/lib/pq#status which recommends using pgx which is actively maintained. Great! All I need is to do, is switch the database driver from pq to pgx. Despite making the change to the “sql.DB” type compatible github.com/jackc/pgx/v4/stdlib … the same type of errors occurred when load testing…

 read tcp 127.0.0.1:XXXXX->127.0.0.1:5432: read: connection reset by peer #6

After some soul searching and a cup of tea, perhaps it has something to do with how the connections are pooled to the database. Unfortunately, it meant a refactor from *sql.DB to *pgxpool.Pool where context needs to be added.

moments later

Yes! The errors have gone away. It also appears much faster. Whatever pgxpool (limiting connections to the database?) is doing, it seems to be working!

Load Testing Locally on My T14s

Java does take a few seconds to get going to generate the machine code under the hood…

Using hey load tester instead of Jmeter:

 

Locally I was seeing Go at ~7457 requests/sec and Java at ~5758 requests/sec once it warmed up. Pretty much the same. However, we should run the original author’s jmeter test with a controlled/reproducible environment…enter the Cloud.

Load Testing Go/Java on AWS

There are three potential bottlenecks:

  1. The client benchmarking tool (as well as the network)
  2. The app
  3. The database

And let's not forget that AWS’s T type instances (virtual machines) are Burstable Performance Instances and might be too variable for benchmarking.

I decided to use m4.large for both bank-{app,db} and run original jmeter benchmark upon the app server and update the Cloudformation to use AWS Linux ECS. Note that I hard-coded the IP address of the database, so you need to change that when you are reproducing results yourself.

I set up my ssh public key like so:

aws --profile dev ec2 import-key-pair --key-name "hendry" --public-key-material fileb://~/.ssh/id_rsa.pub

So my AWS benchmarking workflow was something like:

  1. make delete — tear down Cloud resources
  2. make deploy — bring up the App and Database on the static IP
  3. Wait especially long for the Java version — running mvn seemed to be where it was mostly
  4. benchmark.sh “test-name”

Go — Benchmark 1, Benchmark 2, Benchmark 3 

Java — Benchmark 1, Benchmark 2, Benchmark 3

Conclusions

  • Java takes a lot longer to stand up than Go - not a good candidate for serverless!
  • Orchestration like an ALB health check could be incorporated into the stack though I ran out of time. The instances build the Docker image and it’s not clear when they are ready…
  • Repeated testing on bank-{go,java} resulted in No file descriptors available exhaustion, this appears to be an AWS ECS issue
  • Detailed monitoring via Cloudwatch of the instance was too course grained to tell if the database was the bottle neck… quite a disappointing DX. Further instrumentation is probably needed to work out where the bottle necks lie
  • Go appears a little faster, however more stable from a cold start, with the 99p being far lower ~100ms than Java’s >2000ms .. However, over some runtime, I suspect Java will be more stable.

Not clear what the errors that the original author initially observed, since I think this is how the original author mistakenly concluded that Java could serve twice as many users. In my testing, I could run the tests without errors in either Go/Java stack when I waited patiently for the Java service to be ready, and not run the tests repeatedly as to cause too many open files.

The original author's Go code appears to have had a database connection pool limit issue, which goes away when using pgxpool.

As the Reddit /r/java and YouTube comments suggest, For most tasks Java and Go are completely fine performance-wise. However, I did find Java quite unwieldy, with proponents mandating warm up time for Java, which would certainly result in a problematic Serverless cold start. In comparison, Go has out-of-the-box developer productivity and serverless friendly execution times.

Nonetheless, Java frameworks to their credit are targeting slow startup times with Ahead of Time Compilation (AoT) with GraalVM and Quarkus. It is great to see healthy competition, though currently, Java has some catching up to do!

Java (programming language) Database connection

Published at DZone with permission of Kai Hendry. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Spring Microservice Tip: Abstracting the Database Hostname With Environment Variable
  • Mastering Thread-Local Variables in Java: Explanation and Issues
  • How To Verify Database Connection From a Spring Boot Application
  • Java EE 6 Pet Catalog with GlassFish and MySQL

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!