So, I’m guessing you’ve never written a compiler before…
This is an inherent misunderstanding of both how Java is written, compiled, and ultimately optimized at runtime. Actually, it’s also a lack of understanding of how C++ is compiled and linked as well.
The very nature of Just-in-Time compilation implementations is that they can do runtime optimizations, which given an application running on a wide array of architectures, with a variance in processor support, etc, will not be optimal in all circumstances.
It’s impossible to optimize a pre-compiled, pre-linked application to be optimal across all possible architectures. It’s not impossible for that to happen with a JIT implementation.
Other runtime things you need to care about are memory allocators, the efficiency of garbage collection, and how those are implemented for a given program.
So, what I said remains absolutely true. There are circumstances where Java does indeed outperform C++. With A LOT of effort, you can make C++ program improvements that will make it faster and more efficient than java in all possible cases if you don’t rely only the default allocators for memory management, and if you compile a new version of the program for EVERY possible architecture.
That being said, even if you did all those things above, C++ programs will never be able to perform runtime optimizations, as that’s the very nature of pre-compiled/linked binaries. Now, if you remove the ability for the JVM to do runtime optimization, then what you are saying could be true as long as you go through all of the effort to replace the defaults of the program.
All this talk of optimization is indeed dependent on what the benchmark program actually is, because for example, many years ago when I was in college I wrote a sample application in Java that crushed the C++ implementation of the same program in efficiency. All the program did was spawn and run thousands of basic threads that interacted with read/write locking data structures. Turns out that the Java threads and concurrency locks were typically faster than those of Posix threads and standard library concurrency pieces.
Again, many years ago, posix stuff and fresher versions of C++ may have caught up. However, back then, in that instance Java was significantly faster than C++. Not a very useful benchmark because the program actually didn’t do anything useful in the real world, but it illustrated a point for sure.
No, maybe you’re still learning the nuances here rather than just misrepresenting what I said to form your argument… so I’ll explain.
What I said was “Two instances of a class”. Just in case you aren’t clear on it, primitives in a programming language are different than instances of a class. Instances of a class are the objects that are created by calling a given class definition’s constructor. Primitives are things like integers, doubles, floats, and in some languages (like C++) string literals.
So, nothing I said is related to comparing the equivalence of primitives, what I was saying is that two instances of a class (objects) being compared should thought of as a different case perhaps in the case of equivalence and identity.
Given the Java code:
Integer one_a = new Integer(5);
Integer one_b = new Integer(5);
// What should this return?
(one_a == one-b)
So, what should that return? They are not the same object, so they are not bit for bit identical. So, from the identity perspective, they shouldn’t be considered equal. They are different objects, with different memory layouts, etc.
From the equivalence perspective, they are indeed objects that are trying to represent the integer 5. So they are “equal”, but only from that perspective.
So, the essence of my point is that the equivalence operator doing what it should or should not do is relative to the implementation and design of the class. There’s a reason why you can override the equivalence operator for a class right? Because, the answer to the question as to what should this do is “It depends”.
I believe wholeheartedly you believe that your arguments are logical, and in simplistic terms some of them actually could be. However, the mistakes you think I’ve made in my arguments are really just a lack of understanding of how these things are actually done at the low levels of the architecture.
Hopefully I’ve given you enough keywords that you can Google and find out more for yourself. I wouldn’t expect you to just take my word for it.