Parenthesize expressions to correctly pre-allocate List<T>#2501
Conversation
|
Can you describe the net effect? |
Potentially fewer resizes of E.g. for the first change, With the proposed change to |
The capacity hint only accounted for the dense backing store (temp?.Length); in sparse mode temp is null, so the List was sized to 1 and regrew while adding the _sparse entries. Use _sparse!.Count for that branch, matching the existing '_dense?.Length ?? _sparse!.Count' idiom used elsewhere in the file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
I pushed a follow-up commit (375cb8f) on top of this. While benchmarking I noticed the Which benchmarkThere isn't an existing one that isolates these paths, so I wrote a focused
Mapping to the changes:
benchmark source (ad-hoc, not committed)[MemoryDiagnoser]
[ShortRunJob]
public class GetOwnPropertyKeysBenchmark
{
private Engine _engine = null!;
private Prepared<Script> _denseKeys, _sparseKeys, _numericOwnKeys;
[GlobalSetup]
public void Setup()
{
_engine = new Engine();
_engine.Evaluate("var denseArr = [" + string.Join(",", Enumerable.Range(0, 256)) + "];");
_engine.Evaluate("var sparseArr = []; for (var i = 0; i < 500; i++) Object.defineProperty(sparseArr, i, { value: i, enumerable: true, configurable: true, writable: true });");
_engine.Evaluate("var numObj = {}; for (var i = 0; i < 100; i++) numObj[i] = i; for (var j = 0; j < 16; j++) numObj[Symbol('s' + j)] = j;");
_denseKeys = Engine.PrepareScript("Object.keys(denseArr);");
_sparseKeys = Engine.PrepareScript("Object.keys(sparseArr);");
_numericOwnKeys = Engine.PrepareScript("Reflect.ownKeys(numObj);");
}
[Benchmark] public JsValue DenseArrayKeys() => _engine.Evaluate(_denseKeys);
[Benchmark] public JsValue SparseArrayKeys() => _engine.Evaluate(_sparseKeys);
[Benchmark] public JsValue NumericObjectOwnKeys() => _engine.Evaluate(_numericOwnKeys);
} |
Summary
Parenthesize expressions to correctly pre-allocate
List<T>.Details
As
+binds stronger than??this PR parenthesizes the coalescing parts.See this SharpLab Example for how missing parentheses affect the result.
Linked issue
Test plan
Jint.Testsdotnet test --configuration ReleaselocallyJint.Tests.Test262and confirmed no regressionsJint.Tests/Runtime/InteropJint.BenchmarkBreaking change?
No