Starlark: optimize Dict.plus

`Dict.plus` is used in implementations of `dict` and `dict.update`.

Optimize:
* allocate capacity at construction
* update resulting dict without validation of input dict maps
* iterate underlying maps of input dicts

This test becomes almost two times faster:

```
def test():
    d = {x: x for x in range(100)}
    for i in range(10):
        print(i)
        for j in range(100000):
            dict(d)

test()
```

```
A: N=9, r=5.129+-0.183
B: N=9, r=3.176+-0.155
B/A: 0.619
```

Closes #11785.

PiperOrigin-RevId: 321542802
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Dict.java b/src/main/java/com/google/devtools/build/lib/syntax/Dict.java
index 9855581..905a715 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Dict.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Dict.java
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.syntax;
 
+import static java.lang.Math.max;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import java.util.Collection;
@@ -104,6 +106,10 @@
     this(mutability, new LinkedHashMap<>());
   }
 
+  private Dict(@Nullable Mutability mutability, int initialCapacity) {
+    this(mutability, new LinkedHashMap<>(initialCapacity));
+  }
+
   /**
    * Takes ownership of the supplied LinkedHashMap and returns a new Dict that wraps it. The caller
    * must not subsequently modify the map, but the Dict may do so.
@@ -535,9 +541,10 @@
       Dict<? extends K, ? extends V> left,
       Dict<? extends K, ? extends V> right,
       @Nullable Mutability mu) {
-    Dict<K, V> result = Dict.of(mu);
-    result.putAllUnsafe(left);
-    result.putAllUnsafe(right);
+    Dict<K, V> result = new Dict<>(mu, max(left.size(), right.size()));
+    // Update underlying map contents directly, input dicts already contain valid objects
+    result.contents.putAll(left.contents);
+    result.contents.putAll(right.contents);
     return result;
   }