Sunday, 28 April 2019

String.intern() and performance

In this blog I already wrote about the relationship of cache misses and performance in the KVM virtual machine. I have revisited the topic this weekend with another type of VM: the java virtual machine.

Let's have a list of Strings with some duplication, like (Bob, Sue, Joe, Bob, John, etc). Typically when you read the input from a database or from JSON on a REST API, all strings are a separate object, even if they are the same - like 'Bob' in the example.

Now the question is: how does it change the performance of an algorithm if we de-duplicate this list, therefore each string with the same value should actually be the same String object.

Why would it be any different? Because when the algorithm needs to access the data, it is less likely that it will miss the cache built into the CPU and therefore has to wait.

My benchmark does the same algorithm (sort) first on the non-deduplicated data, and then on the de-duplicated data, on this benchmark we can see the rate of the two results. Of course 1 means they are the same. The different colors show how many different string values there were in the list.

So when does it make sense to deduplicate?
  • Will we elliminate any duplicates?
  • What amount of data is there there be?
  • What is the cost of the deduplication? - e.g. Strings have a constant cost with String.intern
  • For how long / how many times can we enjoy not missing the cache? - typically if you just get the data through JSON and insert it into the DB, then you do not save much time. If you keep the data in memory and process it very frequently, then it with each processing we save a little time
  • Also depends on what type of processing you do, in case of sorting you have to access the data quickly many times after each other. In case of e.g. JSON serialization with jackson, you need to access each data only once, and you can expect smaller difference in performance.

Benchmark source code published on github. Feel free to try, but I have to warn you that it takes 28 hours to run this benchmark.

Sunday, 28 October 2018

Sequence performance

I am frequently getting getting warnings like this from Intellij Idea in kotlin projects:

And if you accept the hint, Intellij will change this into

So what Idea recommends is that if you are performing two or more computations on collections, then you should turn the collection into a sequence and do the computations on those.


Is this always true?

Apparently not. When you transform one list into another list, sequence's seem to consistently under-perform the usual List operations.

When is it right?

When at the end you have to get another list, it does not seem to be a great choice But when you do not want to create another list, you just want to get a sum or avg, that is when it seems to perform always better.

And yes in this case, the transformed code does perform better.

So, having no confirmation of the performance improvement, for now I keep ignoring these hints for the most of my code-base.

Saturday, 27 October 2018

Hackathon lessons

I have been on a hackathon last night, I haven't done this for over a decade. There were a few things I learned:
  1. I am a bad UI engineer, but not terribly bad. Just simply bad. I can live with this :) But also I think I could quickly improve my skills in this direction if I had some time. - meaning at the expense of my other projects
  2. Family duty is difficult to fit together with all-day all-nigh work. Ok, I kind of knew this, but now I know a lot better.

Things that now I remember a lot better (meaning I knew it):
  1. Go prepared. What can be ready ready before the start, must be ready for the start.
  2. Preparation is a team-work. All the team must be prepared. Everyone must have the tools installed on their laptops, they must be tested and working fine, all permissions need to be acquired (like github team membership)
    Also it is better to come to agreement on what tools should be used or preferred.
  3. A hackathon is not about building an application. For that it would be amazingly bad. It is about building an idea, the purpose of everything that you do on the hackathon is to demonstrate that idea.
  4. Perfection is a total enemy in this respect. Whatever works, is fine. Maybe even if it looks crappy. It will be scraped anyway.
    If we are able to demonstrate the idea, someone will have enough time to do this right.
    If we don't not only the code will go to the garbage can, but a potentially valuable idea too.
  5. Be OK with what you have achieved. If you are not, you are discrediting the idea, turning the whole team-effort into a waste.

Wednesday, 8 February 2017

gzip -x

Test subject is a linux LVM volume containing a usual minimal Linux root filesystem, I want to move it to another host. LVM does not give any special tool for moving volumes, so one has to use the "standard" unix commands, this one may be a good candidate:

dd if=/dev/vg/lv-1 | ssh other-server "dd of=/dev/vg/lv-1"

Now of course this is simple, but unfortunately not that good, because if this volume is 2 GB, then we generate 2 GB network traffic, we can try with compression:

dd if=/dev/vg/lv-1 | gzip -N | ssh other-server " gzip -d | dd of=/dev/vg/lv-1"

And now the question is: what should that N be? I have always used 9, but is it that much better than 8?

Centos 7 root filesystem

A blank ext4 filesystem

Now this is the case, where the compression is quick yet I am not satisfied. The problem is that dd does not have a way to skip empty blocks, those too will be transferred. Can gzip help?

That nice drop between 3 and four is interesting. But is it worth waiting 3 seconds to save 7MB transfer? If it does, then your network sucks. Most of the time gzip -1 will do just enough.


More than 5 does not improve significantly on the compression, but comes with a great cost.

gzip -1 may be the best option when we know that the filesystem is mostly empty.

But in any case, an optimization should look for something better than gzip :)