I have to compare two larger objects for equality.
Properties of the objects:
stl::array
.members
will more likely differ than others, therefore lead to a quicker break of the comparison operation if compared first.What is the best way to compare these objects? I see three options:
operator==
.==
and perform a member-by-member comparison, beginning with members likely to differ.==
and view the object as a plain byte field and compare word by word.Some thoughts:
Option 1 seems good because it means the least amount of work (and opportunities to introduce errors).
Option 2 seems good, because I can exploit the heuristic about which elements differ most likely. But maybe it's still slower because built-in ==
of option 1 is ridiculously fast.
Option 3 seems to be most "low-level" optimized, but that's what the compiler probably also does for option 1.
So the questions are:
It is sometimes necessary to compare two values for equality. In some cases, you are testing for value equality, also known as equivalence, which means that the values that are contained by the two variables are equal.
Well, you could write some logic to compare all of the properties of the two objects to each other. This gets complicated when it is an object graph with complex subtypes, so you will need to determine how close is good enough.
Equality comparisons of floating-point values ( double and float) are problematic because of the imprecision of floating-point arithmetic on binary computers. For more information, see the remarks in the topic System.Double.
Every class in java has one parent class that is Object class and it has equals () method to compare two any objects. This program compiles and executes successfully. When the e1.equals (e2) method is invoked it internally compares two object references but not the values. So it has to have a different address.
Default == is fast for small objects, but if you have big data members to compare, try to find some optimizations thinking about the specific data stored and the way they are update, redefining an overloaded == comparison operator more "smarter" than the default one.
As many already said, option 3 is wrong, due to the fact that fields generally are padded to respect the data-alignment, and for optimization reason the bytes added are not initialized to 0 (maybe this is done in the DEBUG version).
I can suggest you to explore the option to divide the check in two stages:
A good question.
If you have some heuristic about which members are likely to differ - use it. So that overloading operator ==
and checking suspected members first seems to be a good idea.
About byte-wise comparison (aka memcmp
and friends) - may be problematic due to struct member alignment. I.e. the compiler sometimes puts "empty spaces" in your struct layout, so that each member will have required alignment. Those are not initialized and usually contain garbage.
This may be solved by explicit zero-initializing of your whole object. But, I don't see any advantage of memcmp
vs automatic operator ==
, which is a members-wise comparison. It probably may save some code size (a single call to memcpy
vs explicit reads and comparisons), however from the performance perspective this seems to be pretty much the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With