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;
}