How does this work?

Am I doing something wrong? I wouldn’t expect the second one to have a faster result…

Output:

Average 1: 7.33694838
Average 2: 4.06036178

package dane.game.model;

import java.util.HashMap;
import java.util.Map;

public class KeyValue {

	private Map<Object, Object> keyvalues = new HashMap<>();

	public <T> T set(Object key, T value) {
		keyvalues.put(key, value);
		return value;
	}

	public <T> T get(Object key) {
		return get(key, null);
	}

	@SuppressWarnings("unchecked")
	public <T> T get(Object key, T defaultValue) {
		if (!keyvalues.containsKey(key)) {
			keyvalues.put(key, defaultValue);
		}
		return (T) keyvalues.get(key);
	}

}

package dane.game.world;

import dane.game.model.KeyValue;

public class Entity extends KeyValue {

	static final int ITERATIONS = 1_000_000;
	static final double NS_TO_MS = 1_000_000.0;

	public static void main(String[] args) {
		Entity e = new Entity();

		// set values
		e.set("x", 0);
		e.set("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", 0);

		double total1 = 0, total2 = 0;

		for (int n = 0; n < 100; n++) {
			long time = System.nanoTime();

			for (int i = 0; i < ITERATIONS; i++) {
				e.get("x");
			}

			total1 += (System.nanoTime() - time) / NS_TO_MS;

			time = System.nanoTime();

			for (int i = 0; i < ITERATIONS; i++) {
				e.get("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
			}

			total2 += (System.nanoTime() - time) / NS_TO_MS;
		}

		System.out.println("Average 1: " + (total1 / 100));
		System.out.println("Average 2: " + (total2 / 100));
	}

}

Trying to write benchmarks in Java is a pain. The optimiser never gets anything done consistently.

If you change the order of the tests you will probably find that the speeds switch the other way around.

Chances are that the JVM just optimises most of it away after a while.

Oh. I switch them around and get about the same exact results. The long string in place of the short string, and vice versa. I guess this means I will have to put my hope on the optimizer then. Thanks for letting me know.

Do you have any opinion on using this KeyValue class for things like storing Entity X/Y which would be constantly read/written to? I imagine it would be more optimized in that case if I were to encapsulate the x/y coordinates in an Object like a Point or something as well. I know it would be muuuch better to just define a field, but I also want to be able to add/remove any variable with any name from an entity.

This code is simply “measuring” (if you can call it that) the JIT warmup time.
By the time the code is optimized the first loop is probably almost done.
Also have to look out for that fact that it can often be smart enough to see that the loops accomplish nothing, and remove them entirely.

If you want any kind of meaningful data out of a Java microbenchmark you’re pretty much going to have to use JMH.
http://openjdk.java.net/projects/code-tools/jmh/
http://java-performance.info/jmh/

HashMaps are pretty bad for cache locality, good ol’ ArrayList has your back 99% of the time. And you know what they say about premature optimization. Have you attempted to time ArrayList etc. vs. Map? I’ll bet List is faster.
It’s also almost guaranteed that you don’t need every last drop of perf anyway. Don’t think too hard about it until you need to.

Actually I was trying to do the opposite of optimization. Giving myself the seemingly worst optimization case scenario for a 2d game I want to make. The point of using a Map is so I could freely add/remove keys and values of any type to my entities.

Why? (for both of those last sentences)

Because I always prematurely optimize things, I want to do the opposite just to mess around. I could make a component system like .add(Component.class, instance) and .get() etc.

So you want to prematurely complicate things? :wink:

I could add listeners to when you set variables too though! ::slight_smile:

Think about the possibilities! :clue:

Might as well go ahead and write an embedded scripting language for all your dynamic variable setting needs!
It’s, uh… webscale!

I will… I think I’ll call it… Lua!

But really, it’s not thaaaat bad, riiiight?