Why instanceof and iterating single list is faster than several specialized lists?

As NoDataFound suggests in the comments, you're not just comparing the performance of iterating through the list, you're also comparing the list population methods. You need to pull this part of your code into a setup method - otherwise you're potentially going to be impacted by resize operations on your three ArrayList instances (amongst other things).

You should also either scrap the use of Random to populate the list, or at least instantiate it with the same seed across both implementations - otherwise you're not creating a repeatable order of elements across both implementations.


The core point is: your measuring is flawed. Not only did that first version of the your question measure different "things", but even the updated question has one big problem, the (way too low) sample size of 10_000!

That is simply not a reasonable sample size. At least, not alone. You should rather check out what you see for 10K, 50K, 100K, 1 million, ... loop iterations.

You see, you make a mistake that many people make with Java: they assume that this or that construct on the source code side of things determines performance.

And that is only partially true. You see, the real performance kicks come out of the myriad optimisations that the JIT compiler within the JVM will do at runtime, based on the profiling information it collected.

I think, the default threshold for the JIT to kick in and translate bytecode into highly optimized machine code is like 90K(?) method invocations/loop iterations.

Please let that sink in: unless your code does something on the scale of 100K or more, the JIT doesn't even consider your code "worth optimising". But then it will kick in, and that can have dramatic effects on overall performance. And then, what you put into your source code ... might not matter much any more.

Thus there isn't a single measurement that tells you what the "best" solution is. That rather depends on the number of iterations you go through.

Thus, the real answer is: java performance benchmarking is hard, and you have to be extremely diligent about what you do, and the conclusions you draw from your results.

Beyond that, the real real answer is: performance is a luxury problem. Of course, one should avoid stupid mistakes that burn CPU cycles for nothing. But besides that, your primary goal is always to write simple code that is easy to read and understand. And then, when you notice "this feels sluggish" or "this doesn't meet our SLAs", then you carefully define experiments to measure what is going on, to identify that piece of code that causes the performance problem. And just for the record: you know which code the JIT can optimise the best ... surprise: simple straight forward code, that looks like code 90% of good java coders tend to write.