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
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
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
Partner Zones AWS Cloud
by AWS Developer Relations
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
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Java
  4. DZone Top Articles of 2011: How to get C like performance in Java

DZone Top Articles of 2011: How to get C like performance in Java

Peter Lawrey user avatar by
Peter Lawrey
·
Jan. 04, 12 · Interview
Like (0)
Save
Tweet
Share
22.68K Views

Join the DZone community and get the full member experience.

Join For Free

This article was selected as one of DZone's most popular, high-quality posts of 2011.  It is now republished as part of a series that will revisit the top articles of 2011 throughout the month of January 2012. 

Overview

Java has many areas which can be slow. However for every problem there is a solution. Many solutions/hacks require working around Java's protections but if you need low level performance it is still possible.

Java makes high level programming simpler and easier at the cost of making low level programming much harder. Fortunately most applications follow the rule of thumb that you spend 90% of your time in 10% of the code. This implies you are better off 90% of the time, worse off 10% of the time. ;)

It makes me wonder why you would write more than 10% of your code in C/C++ for most projects. There will be some projects where C/C++ is the only sensible solution, but I suspect most C/C++ projects would more productive with the use of higher level languages like Java.

One way to get C-like performance is to use C via JNI for key sections of code. If you want to avoid using C or JNI there are still ways you can get the performance you want.

Note: Most of these suggestions only work for standalone applications rather than applets.

Note 2: Use at your own risk. You are likely to need to test edge cases which you wouldn't normally need to worry about when using low level Java.

Fast array access

One area Java can be slower is array access. This is because it implicitly does bounds checking. The JVM is smart enough to optimise checks for loops by checking the first and last element, however this doesn't always apply.

One work around is to use the Unsafe class (which is only available on some JVMs, OpenJDK JVMs do) This class has getXxxx() and setXxxx() for each primitive type and gives you direct access to an object, array or direct memory where you have to do the bounds checking. In native code, these are compiled to single machine code instruction. There is also a getObject(), setObject() methods however I suspect that they don't provide as much of a performance improvement (by the time you access the Object as well)

You can check the native code generated for a method by downloading the debug version of the OpenJDK and getting it to print the compiled native code.

Arbitrary memory access

You can use the Unsafe class again for arbitrary access, however a "friendlier" way is to use a DirectByteBuffer and change its address and limit as desired (via reflection or via JNI) This will give you a Buffer which points to a random area of memory such as device buffer.

Using less memory

This is not as much of an issue as it used to be. A 16 GB server costs $1000 and a 1 TB server costs about $70K.

However, cache memory is still a premium and for some applications and its worth cutting memory consumption. A simple thing to do is to use Trove which support primitives in collections efficiently. If you have a large table of data, you can store data by column instead of by row (if you have lots of rows of data, and a few columns). This can improve caching behaviour if you are scanning data by field but don't need all fields.

You can also use Direct memory to store data how you wish. This is what the BigMemory library uses.

Stream based IO is slow and NIO is a pain to use

How can use you have the best of both worlds? Use blocking IO in NIO (which is the default for a Channel) Don't use Selectors unless you need them. In many cases, they just add complexity. Most systems can handle 1K-10K threads efficiently. If you need more connections than that, buy another server, a cheap one cost about $500.

Fast Efficient Strings

Java 6 update 21 has an option -XX:+UseCompressedStrings which can use byte[] instead of char[] for the strings which don't need 16-bit characters. For many applications this saves memory but is slower. (5%-10%)

Instead you can use your own Text type which wraps a byte[], or get you text data from ByteBuffer, CharBuffer or use Unsafe.

Faster Startup times

Java tends to have slow startup times when you load in lots of bloated libraries. If this is really a problem for you load less libraries. Keeping them to a minimum is good practice anyway. Do this and your startup times will be a few seconds (not as fast as C, but likely to be fast enough)

Less GC pauses

Most Java libraries create objects freely and generally this is not a problem.

However this doesn't mean you can't pre-allocate your objects, use Direct ByteBuffers and Object recycling techniques to minimise your object creation. By increasing the Eden size you can have an application which rarely GCs. You may even reduce it to one GC per day (say as a scheduled over night job)

Source:  http://vanillajava.blogspot.com/2011/05/how-to-get-c-like-performance-in-java.html
Java (programming language) DZone

Published at DZone with permission of Peter Lawrey, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 10 Easy Steps To Start Using Git and GitHub
  • Cucumber.js Tutorial With Examples For Selenium JavaScript
  • GitLab vs Jenkins: Which Is the Best CI/CD Tool?
  • How To Build an Effective CI/CD Pipeline

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: