Архив рубрики: Uncategorized

Playing with JMH

When I tried to measure something with JMH, I created few methods which returned simple ints.

Like this:

public int return0() { return 0; }
public int return1() { return 1; }
public int return2() { return 2; }

And I was very (VERY) surprised with results.

Benchmark Mode Thr Count Sec Mean Mean error Units
t.SimpleReturns.return0 thrpt 1 100 1 339506,793 5390,430 ops/ms
t.SimpleReturns.return1 thrpt 1 100 1 744749,512 15169,150 ops/ms
t.SimpleReturns.return2 thrpt 1 100 1 503420,254 16123,554 ops/ms
API replied benchmark score: 339506.7927333333 ops/ms over 100 iterations
API replied benchmark score: 744749.5115 ops/ms over 100 iterations
API replied benchmark score: 503420.2544833333 ops/ms over 100 iterations

jdk1.8.0_25 on Windows 8.1 was used.

You just think about this, returning 1 is faster than return 0!

What about your test results?…

 Update: Seems this difference was here due to JMH 0.1 version, in latest (1.6) these methods runs roughly same time.

Java Maven Deterministic Builds of Jar War Ear

How it happens that when you compile same code twice — you get different files? How to avoid this, how to get deterministic builds — builds, which are depends on what and how are building, and not when.  Or other question — how to make sure that these binaries are produced from this source code, and without extra manipulation?

That’s a serious question, currently raised amongst many project, like Debian, FreeBSD, bitcoinj and many more.

What about Java? Java itself not guaranteed same bytecode produced with different version of compiler; But at least if environment unchanged, then the code produced from *.java files are same.

So, in theory it’s not hard to get deterministic builds at least in one environment scope. In reality it’s harder than that, since classes usually packed in jar/war/ear (which all are really zip files under the hood). These archives storing timestamps of packed files, and what worse, Jar working differently with Manifest files.

To solve this problem, I created maven plugin (two actually) and it appears that they just works for me. To get deterministic builds in your project, just add these to build/plugins section in your pom.xml (you can even add this only to your parent pom.xml)

        <id>1. stamp files</id>
        <id>2. recreate archive</id>
        <id>3. Move deterministic archive into default name</id>
                <move todir="${project.build.directory}" includeemptydirs="false">
                    <fileset dir="${project.build.directory}">
                        <include name="*ar"/>
                    <mapper type="regexp" from="(.*)-det.(.*)" to="\1.\2"/>

So, what magic are happening there?

First execution of detarchive plugin is touch-classes goal, which changes all timestamps of all files inside «classes» directory (can be configured via configuration parameter targetDirectory). Files are stamped using configuration parameter stamp. If you don’t like default format — yyyyMMddHHmmss, you can use your own custom format, just don’t forget specify it via stampFormat.

After classes and resources stamped, it packed by maven into jar, and also could be jar dependencies, pom.xml and somethinng more. After packing maven jar, we need to polish it, using goal repack. This goal smart enough to run without parameters, but if you want something else — you can specify in configuration these parameters: outputDirectorystamp, stampFormat — same usage as in touch-classes goal. If they aren’t specified, timestamp coming from most frequent timestamp amongst *.class files.

And additional parameters

  • archiveSuffix (by default it’s «-det» )
  • archiveName (which archive to repack, by default it’s found automagically)
  • skipPomProperties (default true, due to maven change each time content of pom.properties — and really, who need this file anyway)
  • skipFiles (array of filenames, which files should not get into resulting jar, if you have some nasty file somehow packed into your archive, you can define here to skip it)
  • manifestName (default «META-INF/MANIFEST.MF» — in case you need to change default name into something weird)

After we repacked archive, let’s replace it into default name, it achieved via maven-antrun-plugin and regexp globber. Which I think mostly self-explanatory.

Enjoy you Java deterministic builds :)

Cali alpha release #2

Today I announce that Cali alpha #2 is ready for internal testing.

It took me about year to make basic documentation and internal structure, but it was fun!

So, for those who just joined — CALI is new programming language paradigm,  language and framework.

Main idea is that basic language unit is not function nor class, but it’s some abstract abstraction in abstract knowledge storage.

Doh, it was pretty hard to explain for my alpha-testers, I need to go work on better «getting started».

Anyway, CALI is happening soon, stay tuned!

Skype lagging as hell in Windows 8 — solved

There are some weird and obscure ways to program things. Such ways can lead to what we have currently in Skype under Windows 8/8.1:

If you have not IE as default browser, your Skype eats up CPU and lags as hell.

And make IE as your default browser is NOT a solution — since we don’t cooperate with bad guys and dirty methods 😉

Actually there is simpler workaround:

Turn off all systray event notices

Turn off «Display avatar in contact list»

That’s it! Maybe you’ll be forced to read all messages and restart Skype before lags stops, but at least you have now way.