Add short circuiting returns to equals method in OptionsBase.

asMap() is expensive as it reflectively aggregates all fields into a map. We can return quickly if they are the same instance or instances of differing classes. If we do get to comparing different instances of the same class, we can return as soon as we find a differing option field.

RELNOTES: None.
PiperOrigin-RevId: 244687761
diff --git a/src/main/java/com/google/devtools/common/options/OptionsBase.java b/src/main/java/com/google/devtools/common/options/OptionsBase.java
index e981427..804c94a 100644
--- a/src/main/java/com/google/devtools/common/options/OptionsBase.java
+++ b/src/main/java/com/google/devtools/common/options/OptionsBase.java
@@ -19,6 +19,7 @@
 import com.google.common.escape.Escaper;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * Base class for all options classes. Extend this class, adding public instance fields annotated
@@ -119,8 +120,21 @@
   }
 
   @Override
+  @SuppressWarnings("EqualsGetClass") // Options can only be equal if they are of the same type.
   public final boolean equals(Object that) {
-    return that instanceof OptionsBase && this.asMap().equals(((OptionsBase) that).asMap());
+    if (this == that) {
+      return true;
+    }
+    if (that == null || !getClass().equals(that.getClass())) {
+      return false;
+    }
+    OptionsBase other = (OptionsBase) that;
+    for (OptionDefinition def : OptionsParser.getOptionDefinitions(getClass())) {
+      if (!Objects.equals(getValueFromDefinition(def), other.getValueFromDefinition(def))) {
+        return false;
+      }
+    }
+    return true;
   }
 
   @Override