You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by er...@apache.org on 2020/09/01 14:04:56 UTC

[lucene-solr] branch master updated: SOLR-14579: Comment SolrJ 'Utils' generic map functions

This is an automated email from the ASF dual-hosted git repository.

erick pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/master by this push:
     new b421878  SOLR-14579: Comment SolrJ 'Utils' generic map functions
b421878 is described below

commit b421878b77b7b9c6daae838a8bd2057f599ecc1f
Author: Erick Erickson <Er...@gmail.com>
AuthorDate: Tue Sep 1 10:04:44 2020 -0400

    SOLR-14579: Comment SolrJ 'Utils' generic map functions
---
 .../java/org/apache/solr/common/util/Utils.java    | 42 ++++++++++++++++++++--
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
index 8fd137b..6aaa4d7 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
@@ -94,7 +94,44 @@ import static java.util.Collections.unmodifiableList;
 import static java.util.Collections.unmodifiableSet;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
+
 public class Utils {
+  // Why static lambdas? Even though they require SuppressWarnings? This is
+  // purely an optimization. Comparing:
+  //
+  //    mapObject.computeIfAbsent(key, o -> new HashMap<>());
+  //
+  //    vs.
+  //
+  //    mapObject.computeIfAbsent(key, Utils.NEW_HASHMAP_FUN)
+  //
+  //
+  //    The first code fragment is executed as following
+  //
+  //    s.computeIfAbsent(key, new Function() {
+  //      @Override
+  //      public Object apply(String key) {
+  //        return new HashMap<>();
+  //      }
+  //    }
+  //
+  //    So, there are two problems with this
+  //
+  //    A new anonymous inner class is created for that lambda. This one extra
+  //    class becomes a part of your binary a new instance of that class is
+  //    created everytime the computeIfAbsent() method is invoked, irrespective
+  //    of whether the value is absent for that key or not. Now imagine that
+  //    method getting called millions of times and creating millions of such
+  //    objects for no reason
+  //
+  //    OTOH
+  //
+  //    Utils.NEW_HASHMAP_FUN
+  //    Only a single anonymous class is created for the entire codebase
+  //    Only single instance of that object is created in the VM
+  //
+  // See SOLR-14579.
+
   @SuppressWarnings({"rawtypes"})
   public static final Function NEW_HASHMAP_FUN = o -> new HashMap<>();
   @SuppressWarnings({"rawtypes"})
@@ -236,7 +273,7 @@ public class Utils {
     }
 
     @Override
-    @SuppressWarnings({"unchecked", "rawtypes"})
+    @SuppressWarnings({"rawtypes"})
     public void handleUnknownClass(Object o) {
       if (o instanceof MapWriter) {
         Map m = ((MapWriter) o).toMap(new LinkedHashMap<>());
@@ -404,7 +441,6 @@ public class Utils {
     return getObjectByPath(root, onlyPrimitive, parts);
   }
 
-  @SuppressWarnings({"unchecked"})
   public static boolean setObjectByPath(Object root, String hierarchy, Object value) {
     List<String> parts = StrUtils.splitSmart(hierarchy, '/', true);
     return setObjectByPath(root, parts, value);
@@ -693,7 +729,7 @@ public class Utils {
    * @param input the json with new values
    * @return whether there was any change made to sink or not.
    */
-  @SuppressWarnings({"unchecked", "rawtypes"})
+  @SuppressWarnings({"unchecked"})
   public static boolean mergeJson(Map<String, Object> sink, Map<String, Object> input) {
     boolean isModified = false;
     for (Map.Entry<String, Object> e : input.entrySet()) {