简体   繁体   中英

First time execution performance of Java

I've been developing a Reporting Engine (RE is to generate PDF-reports) in C++ on Linux. If a PDF-report being generated must contain some charts, I need to build them while building the report. ChartBuilder is written in Java (with JFreeChart of Java-TeeChart - it does not matter anyway). Well, while RE is building a report, it invokes some ChartBuilder-API functions via JNI to build a chart (or several charts) step by step (ChartBuilder is packed into .jar-file). The problem is that it takes a lot of time to build the first chart (that is, to execute every ChartBuilder-API function for the first time during the process lifetime)! More specifically, it takes about 1.5 seconds to build the first chart. If there are several charts to be created, the rest of charts are built during about (~0.05, ~0.1) seconds. That is 30 times faster than the first one! It's worth to note, that this first chart is the same with the rest of them (except for data). The problem seems to be fundamental for Java (and I'm not very expirienced in this platform). Below is the picture that illustrates described problem:

在此处输入图片说明

I wonder if there is a way to hasten the first execution. It would be great to understand how to avoid the overhead on the first execution at all because now it hampers the whole performance of RE.

In addition I'd like to describe the way it works: Somebody invokes C++RE::CreateReport with all needed parameters. This function, if it's needed, creates a JVM and makes requests to it via JNI. When a report is created, the JVM is destroyed.

Thanks in advance!

Just-in-time compilation . Keep your JVM alive as a service to avoid paying JIT compilation cost multiple times.

I this it is likely a combination of things as people have pointed out in the comments and other answer - JVM startup, class loader, the fact that Java 'interprets' your code when it is running it etc.

Most fall into the category of 'first time start up' overhead - hence the higher performance in subsequent runs.

I would personally be inclined to agree with Thomas (in the comments to your question) that the highest overhead is possibly the class loader.

There are tools you can use to profile the Java JVM to get a feel for what is taking the most time within the JVM itself - such as:

You have to be careful using these tools to interpret the results with some thought - you may want to measure first runs and subsequent runs separately, and you also may want to add your own system timings into your C++ code that wraps the JNI calls to get a better picture of the end to end timings. With performance monitoring, multiple test runs are very important to allow for slow and fast individual runs for one reason or another (eg other load on the computer - even on a non shared laptop).

As LeffeBrune mentions if you can have the chart builder running as a service already, it will likely speed up the first run, although you will probably need to experiment to see how much difference it makes if it has not actually been running on a processor for a while, for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM