Tag Archives: netbeans

Java micro benchmark with jmh and Netbeans

Note that jmh has evolved significantly since I wrote this post and some of the information below might be obsolete.

jmh (Java Microbenchmark Harness) is an open source micro-benchmarking tool for java, part of the OpenJDK. I have been using it for a few weeks and found it easy to use and very useful. One advantage it has over Caliper is that it runs on Windows.

Installation

The installation process is fairly straight-forward using Maven. For example, with Netbeans, it can be done following those steps:

  • Download source (you need to have Mercurial installed):

  • Open, compile and install the library:

    • Netbeans then proposes to open the project: click Open Projects
    • Select the top project and click open
    • Right click on the project > Custom > Goals
    • In Goals, type: clean install -DskipTests=true

Create a Microbenchmark Project

  • Menu File > New Project
  • Select Maven / Java Application > Next
  • Let’s call it performance
  • Enter a GroupID (I use com.assylias for this example)
  • Click Finish

Let’s now configure the dependencies and allow the project to run jmh:

  • In the project’s Project Files, select and edit pom.xml
  • Use the following dependencies and build settings:

<dependencies>
    <dependency>
        <groupId>org.openjdk.jmh</groupId>
        <artifactId>jmh-core</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.0</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <finalName>microbenchmarks</finalName>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>org.openjdk.jmh.Main</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Sample benchmark

Let’s try to benchmark something to see if it works. We could for example try to find the best method to copy an array. The four candidates we are going to test are:

  • Object[] newArray = originalArray.clone();
  • Object[] newArray = Arrays.copyOf(originalArray, originalArray.length);
  • System.arrayCopy(originalArray, 0, newArray, 0, originalArray.length);
  • and a plain old loop

In your project source package, right click and add a new class, let’s call it ArrayCopy, and copy the following code:

import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.BenchmarkType;
import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;

/**
 *
 */
@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class ArrayCopy {

    private int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
    public int[] clone_() {
        int[] copy = array.clone();
        return copy;
    }

    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
    public int[] arrayCopy() {
        int[] copy = new int[array.length];
        System.arraycopy(array, 0, copy, 0, array.length);
        return copy;
    }

    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
    public int[] copyOf() {
        int[] copy = Arrays.copyOf(array, array.length);
        return copy;
    }

    @GenerateMicroBenchmark(BenchmarkType.AverageTimePerOp)
    public int[] loop() {
        int[] copy = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            copy[i] = array[i];
        }
        return copy;
    }    
}

Finally, let’s create the launcher that will run the micro-benchmark – I use this runner class (alternatively you can run it from the command line but I’m lazy and prefer running it from the IDE):

import java.io.IOException;
import org.openjdk.jmh.Main;

public class RunTest {
    private static final String TEST = ".*ArrayCopy.*"; //uses regexp

    public static void main(String[] args) throws IOException {
        Main.main(getArguments(TEST, 5, 5000, 1));
    }

    private static String[] getArguments(String className, int nRuns, int runForMilliseconds, int nThreads) {
        return new String[]{className,
            "-i", "" + nRuns,
            "-r", runForMilliseconds + "ms",
            "-t", "" + nThreads,
            "-w", "5000ms",
            "-wi", "3",
            "-v"
        };
    }
}

Clean and Build the project (CTRL+F11) and run it (SHIFT+F6 with the RunTest class selected).

You should get a detailed output of the performance of the various methods and a summary table that looks like this:

Benchmark                       Thr    Cnt  Sec         Mean   Mean error          Var    Units
c.a.p.g.a.ArrayCopy.arrayCopy     1     10    1       11.947        0.049        0.002  nsec/op
c.a.p.g.a.ArrayCopy.clone_        1     10    1       11.801        0.368        0.128  nsec/op
c.a.p.g.a.ArrayCopy.copyOf        1     10    1       11.783        0.115        0.013  nsec/op
c.a.p.g.a.ArrayCopy.loop          1     10    1       17.985        0.109        0.011  nsec/op

Next steps

The jmh project comes with a few samples which are very interesting and useful to read. It is also useful to check the usage, for example with the printUsage method in the example above (or by running it from the command line with no argument: java -jar microbenchmarks.jar).

Tagged , , , ,

Adding TestNG support in Netbeans

Setup Environment

  • Install the TestNG for Ant plugin
  • In the Installed plugin list, make sure it is activated – if not activate it.
  • Restart Netbeans
  • In project.properties, look for a line that sets javac.test.classpath and add a new line below: j2ee.platform.classpath=$(javac.test.classpath)

      TestNG is now available by doing a right click.

      ===== EDIT ======
      The integration is not great and I have decided to remove it in the end.

Tagged , ,

Basic Build Management in Netbeans

The idea of multiple build management is to be able to have several entry points in a project (i.e. Main classes) and be able to build one or the other, with its own parameters, in one click.

Configuration setup

Creating different configurations is the easy part:

  1. Right click on the project in the Projects View
  2. Set Configuration / Customize
  3. In the popup window, click on New and define the Main class associated with that configuration

Let’s assume we now have 2 configurations called Drawing and Printing.
We want to change the build to make sure that the jar file has the right name and to create a version.info file in the distribution folder that gives information about the version. Drawing is on version 1.0 and Printing on version 1.5.

Build Setup

Property Files

We start by adding a property to the config files, found in the nbproject/configs folder, accessible from the Files View in Netbeans:
Drawing.properties file:

jar.name=Drawing.jar
version.num=1.0

Printing.properties file:

jar.name=Printing.jar
version.num=1.5

Common build tasks

Then we add some ant tasks in the -post-jar target in the build.xml file, accessible from the Files View too:

    <target name="-post-jar">
        <!-- Creates a Version info file -->
        <echo file="${dist.dir}/version.info" message="Version number: ${version.num}" />
        <!-- Renames the jar file -->
        <move file="${dist.jar}" tofile="${dist.dir}/${jar.name}" />       
    </target>    

Specific tasks

For the Drawing project, we also want to delete the README.TXT file that Netbeans automatically generates.
We create a new build file called build-drawing.xml with the following content:

<?xml version="1.0" encoding="UTF-8"?>

<project name="Project" default="default" basedir=".">
    <import file="build.xml" as="common"/>
    <!-- Depends forces the inclusion of what is in the common build file, which would be overriden otherwise -->
    <target name="-post-jar" depends="common.-post-jar">
         <delete file="${dist.dir}/README.TXT"/>
    </target>
</project>

Finally, we let Netbeans know that it has to use this new build file by adding a line to the Drawing.property file:

buildfile=build-drawing.xml

Deployment

Finally, we want to automatically deploy the distribution to a network drive by copying the whole directory.
We add a deploy target in the build script by adding the following lines to build.xml:

    <!-- 
                ======================
                    DEPLOY SECTION 
                ======================
            -->

    <!-- Deploy to server if possible -->
    <target name="check-deploy">
        <condition property="deploy-is-true">
            <and>
                <available file="${dist.dir}/${jar.name}"/>
                <not> <equals arg1="${deploy.dir}" arg2=""/> </not>
                <available file="${deploy.dir}" type="dir"/>
            </and>
        </condition>
    </target>
    <target name="do-deploy" depends="check-deploy" if="deploy-is-true">
        <echo level="info">Deploying application</echo>
        <copy todir="${deploy.dir}">
            <fileset dir="${dist.dir}"/>
        </copy>
    </target>
    <target name="dont-deploy" depends="check-deploy" unless="deploy-is-true">
        <echo level="info">Application cannot be deployed</echo>
    </target>

    <target depends="clean,jar,check-deploy,do-deploy,dont-deploy" description="Deploy project." name="deploy"/>

We also add a property to the property files:

deploy.dir=S:/Deployment Folder/

You now only need to right click in the ant script and select the newly created “deploy” target to execute that script, which cleans, builds and deploys the project.

Bonus: Mercurial Changeset ID

Finally, we want to include the Mercurial changeset ID to the Version.info file. Let’s also include the build time. This is the full script contained in the common build file:

<?xml version="1.0" encoding="UTF-8"?>

<project name="Common Build" default="default" basedir=".">
    
    <import file="nbproject/build-impl.xml"/>

    <target name="-post-init" description="Get the changeset ID of the current build">
        <exec outputproperty="hg.changeset" executable="hg">
            <arg value="id" />
            <redirector>
                <outputfilterchain>
                    <tokenfilter>
                        <replaceregex pattern=" tip" replace="" flags="g"/>
                    </tokenfilter>
                </outputfilterchain>
            </redirector>
        </exec>
        <tstamp>
            <format property="NOW" pattern="yyyy-MM-dd HH:mm:ss z" />
        </tstamp>
    </target>

    <target name="-post-jar">
        <!-- Creates a Version info file -->
        <echo file="${dist.dir}/version.info" message="Version number: ${version.num}${line.separator}Mercurial Changeset ID: ${hg.changeset}${line.separator}Build time: ${NOW}${line.separator}" />
        <delete file="${dist.dir}/README.TXT"/>
        <move file="${dist.jar}" tofile="${dist.dir}/${jar.name}" />       
    </target>     

    <!-- 
                ======================
                    DEPLOY SECTION 
                ======================
            -->

    <!-- Deploy to server if possible -->
    <target name="check-deploy">
        <condition property="deploy-is-true">
            <and>
                <available file="${dist.dir}/${jar.name}"/>
                <not> <equals arg1="${deploy.dir}" arg2=""/> </not>
                <available file="${deploy.dir}" type="dir"/>
            </and>
        </condition>
    </target>
    <target name="do-deploy" depends="check-deploy" if="deploy-is-true">
        <echo level="info">Deploying application</echo>
        <copy todir="${deploy.dir}">
            <fileset dir="${dist.dir}"/>
        </copy>
    </target>
    <target name="dont-deploy" depends="check-deploy" unless="deploy-is-true">
        <echo level="info">Application cannot be deployed</echo>
    </target>

    <target depends="clean,jar,check-deploy,do-deploy,dont-deploy" description="Deploy project." name="deploy"/>

</project>
Tagged , ,

Code Coverage in Netbeans

Headache to get the Netbeans code coverage plugin working in Netbeans 7.xx, until you find that page:

http://plugins.netbeans.org/plugin/38945/unit-tests-code-coverage-plugin-updated-for-netbeans-7-0

  1. Download
  2. Unzip somewhere, say in the Netbeans folder
  3. Tools / Plugins / Downloaded / Add Plugins…
  4. Test the project (ALT+F6)
  5. Et voila
Tagged ,