Is it sensible optimization
It isn't an optimization at all unless you can measure an improvement. It's just optimizy-looking cargo-cult junk, like go-faster stripes.
(That's not an insult - everyone is susceptible to wanting their code to be fast, and this often leads you to write code that looks fast. The solution is to learn not to trust appearances and instead to develop the habit of profiling your code properly).
However, there is no information about how fast those operations are
Don't write extra code unless you have a reason to.
Here, you don't have any reason to believe the longer version is more correct or that it performs better. The only thing we know for sure is that we added some cognitive overhead (there's more code to read) and a test-and-branch (or conditional move).
We should be required to justify writing more and more complex code - which here we cannot. IME this is just as likely to be worse than the naive version because the test-and-branch spills the branch predictor, or because of the load dependency, or because of the extra instruction cache pressure.
Edit:
UPD: Imagine, we are building a library
If you expect the things being stored may be very expensive to copy but cheap to compare, it'd be easier to provide an optional wrapper for the value type instead of baking it into your container:
template <typename T>
class CheapCompareExpensiveCopy
{
T value_;
public:
using SelfT = CheapCompareExpensiveCopy<T>;
// usual constructors etc.
SelfT& operator=(SelfT const &other)
{
if (other.value_ != value_) {
value_ = other.value_;
}
return *this;
}
};