There's a problem with your benchmarks: your benchmarks for MJE solution will vary depending upon the contents of the private data control of the class and which OS you're running on.
The solution posted by ShaunR is going to be the stable option regardless of the contents of the class. The performance of the MJE method will vary greatly depending upon the private data control of the objects being compared. Going through the Preserve Run-Time Class primitive will require a new allocation every time (because the wire starts with an instance of LabVIEW Object, copied from the constant, which is deallocated in favor of a new handle pointing to an object of the middle terminal's class). On a desktop system, that handle will just be assigned to point at the default value, since LV shares only one copy of the default value, but on real-time targets, that would be a full allocation (because everything has to be preallocated to avoid jitter in the event that the object gets passed into a deterministic section). Then we get to the equals primitive. In the case where the types do not match, you'll get a very quick answer because the type pointers can be compared. But if the types do match, if the class contains non-trivial data fields, you'll have the time overhead of actually comparing the fields. On a desktop system, again, we'll notice that they both point to the default value and you'll get a quick answer, but on real-time, we'll actually run the comparison proc to see if the values come out the same.
Now, if you're on a desktop system, the MJE, as I described above, does really well. I am guessing that this one would do even better:
Yes, that's a hardcoded zero iteration For Loop with the class wires wired across using tunnels, not shift registers. It does the job. I haven't benchmarked it -- you're free to do so -- but it avoids the type comparison work entirely that the Preserve Run-Time Class primitive does.
Having said all of that, even on RT, I would probably not use the stable solution because it requires the construction of those interim variants, which is a memory allocation. I just figured you should be aware of the trickiness of benchmarking this stuff.
On a completely unrelated topic, MJE, you can replace the error generation code you've got with this:
It's a lot simpler. The VI is in the palettes near the General Error Handler.vi.
Oh... and the path solution does have one problem: if a class has never been saved, the path will be empty.