QuinnF
QuinnF

Reputation: 2209

Optimizing performance by removing duplicate BufferedImages / Fast way to compare BufferedImages in Java

I'm working on a Java app where I'm procedurally instantiating a potentially large number of instances of an object, which each have an icon (a BufferedImage), which is chosen (based on random parameters) from a bank of 10 or 20 32x32 PNG's.

In order to optimize performance, I had the idea to load the images into a static ArrayList instead of storing them as a parameter. Then, when I instantiate an object, I check if the ArrayList contains the objects icon. If not, it loads it, but if it does, it just saves the index of the image and looks it up whenever it needs it. This is probably a little slower on a small scale but caps a little bit of the memory use as the as the number of objects becomes much greater than the possible number of icons.

Given the size of the images and the number that I will likely have, I don't think this implementation will make much of a performance difference either way, but it just feels bad to store all these duplicate BufferedImages, and it's an interesting exorcise in performance.

My question is, firstly, is this necessary at all? Is there a better way to do this? or does the Java virtual machine / cache / some other process do some of this work for me?

After that, what is the fastest way to compare BufferedImages? This question has been asked a few other places and I've never seen a very good answer. The naive approach would be to compare every pixel of the image data one at a time, but this seems unnecessarily slow. I considered using a collision-resistant hash function, but since most of the standard ones are designed for Cryptography, they are unnecessarily complex and intentionally very slow. The best idea I've had for this so far seems to be to just create a custom image class, extending BufferedImage, which has a field for the src/url of the image, and then just set that every time an image is loaded, and compare based off that.

Upvotes: 0

Views: 133

Answers (1)

Robby Cornelissen
Robby Cornelissen

Reputation: 97382

The best idea I've had for this so far seems to be to just create a custom image class, extending BufferedImage, which has a field for the src/url of the image, and then just set that every time an image is loaded, and compare based off that.

If this is valid for your use case, i.e. if there's a one-to-one mapping between images and URLs, just create a map with the URL strings as keys, and the images as values:

Map<String, BufferedImage> images = new HashMap<>();

You can then easily retrieve from the map based on the URL:

BufferedImage image = images.get("whatever");

Alternatively, you can use a cache implementation like Guava's.

Upvotes: 2

Related Questions