Skip to content

Dart2JS should inline spreads of literals in collections #62226

@lrhn

Description

@lrhn

In an expression like:

var list = <int>[
 e1,
 if (b) ...[e2, e3],
 e4
];

the compiler should inline the addition of the e2 and e3 values to the list without allocating a new list and calling addAll with it.

That is, the compilation of the expression above should effectively be the same as:

  var _$tmp = <int>[];
  _$tmp.add(e1);
  if (b) {
    _$tmp.add(e2);
    _$tmp.add(e3);
  } 
  _$tmp.add(e4);
  var list = _$tmp;

and NOT:

  var _$tmp = <int>[];
  _$tmp.add(e1);
  if (b) {
    _$tmp.addAll([e2, e3]);
  } 
  _$tmp.add(e4);
  var list = _$tmp;

The current dart compile js -O4 code of such a list literal contains an allocation of an array and a call to .addAll.

This optimization is always safe when the literal is a list, whether the outer collection is a set or list.
It's not safe to inline a set literal, [...{e2, e3}], not without doing something else to ensure that only the last of two equal expression valuse is added. However, spreading a set into a set is safe, {e1, ...{e2, e3}, e4} is the same as {e1, e2, e3, e4}.

It's also safe to inline map literal spreads into map literals. Adding the equal keys more than once will always use the first key instance and the last value, and adding an insertion-ordered map literal to a map does the same thing.

(I'm fairly sure it's an invisible optimization. I'd hate if there is some way that it differs, because that would mean that ...[e1, e2] doesn't do what I expect it to do!)

So:

  • No addAll in a list literal when spreading a list literal.
  • No addAll in a set literal when spreading a list or set literal.
  • No addAll in a map literal when spreading a map literal.

In all these cases, the addition should just be made directly to the outer collection, instead of first being added to a nested collection, which is then addAll'ed to the outer collection.

Should be a simple optimization, and I want to recommend ...[e1, e2] as the way to write grouped elements.

(I've filed this against the VM too, #62225. If this can be optimized in the CFE, especially if already using a CFE lowering of collection elements, then that may be a better place to do it.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-web-jsIssues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop.type-performanceIssue relates to performance or code sizeweb-dart2js

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions