Be more verbose in loops etc in kernel
Benchmarks have shown that old-style for-loops are faster than for-in
for instance.
Golem says
ia32
whole stack (i.e. including utf8 and change to VariableIndexer)
AstToBinaryP90 (Intel Core i5) 6.617% (0.4 noise)
AstToBinary (Intel Xeon) 5.158% (0.4 noise)
AstToBinaryP90 (Intel Xeon) 5.104% (0.4 noise)
AstToBinaryP50 (Intel Xeon) 5.148% (0.4 noise)
AstToBinary (Intel Core i5) 6.579% (0.4 noise)
AstToBinaryP50 (Intel Core i5) 6.741% (0.4 noise)
by itself (i.e. compared to a build with utf8 and change to VariableIndexer)
AstToBinaryP90 (Intel Core i5) 0.7724% (0.0 noise)
AstToBinaryP50 (Intel Core i5) 0.7848% (0.0 noise)
AstToBinary (Intel Core i5) 0.8559% (0.0 noise)
AstToBinaryP90 (Intel Xeon) 0.7730% (0.1 noise)
AstToBinaryP50 (Intel Xeon) 0.8195% (0.1 noise)
AstToBinary (Intel Xeon) 0.9319% (0.1 noise)
x64
whole stack (i.e. including utf8 and change to VariableIndexer)
AstToBinaryP90 (Intel Core i5) 5.555% (0.2 noise)
AstToBinaryP50 (Intel Xeon) 6.352% (0.4 noise)
AstToBinaryP50 (Intel Core i5) 5.395% (0.5 noise)
AstToBinary (Intel Xeon) 6.928% (0.5 noise)
AstToBinaryP90 (Intel Xeon) 7.180% (0.5 noise)
AstToBinary (Intel Core i5) 5.824% (0.5 noise)
by itself (i.e. compared to a build with utf8 and change to VariableIndexer)
AstToBinaryP90 (Intel Core i5) 0.1039% (0.0 noise)
AstToBinaryP50 (Intel Core i5) 0.6154% (0.0 noise)
AstToBinary (Intel Core i5) 0.7640% (0.1 noise)
AstToBinaryP50 (Intel Xeon) 1.268% (0.1 noise)
AstToBinary (Intel Xeon) 1.457% (0.1 noise)
AstToBinaryP90 (Intel Xeon) 1.512% (0.1 noise)
Change-Id: If091a3a01f2fe6574712946a01644413033739b6
Reviewed-on: https://dart-review.googlesource.com/c/85341
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 3006953..78bc419 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -383,16 +383,20 @@
void computeCanonicalNames() {
assert(canonicalName != null);
- for (var typedef_ in typedefs) {
+ for (int i = 0; i < typedefs.length; ++i) {
+ Typedef typedef_ = typedefs[i];
canonicalName.getChildFromTypedef(typedef_).bindTo(typedef_.reference);
}
- for (var field in fields) {
+ for (int i = 0; i < fields.length; ++i) {
+ Field field = fields[i];
canonicalName.getChildFromMember(field).bindTo(field.reference);
}
- for (var member in procedures) {
+ for (int i = 0; i < procedures.length; ++i) {
+ Procedure member = procedures[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
}
- for (var class_ in classes) {
+ for (int i = 0; i < classes.length; ++i) {
+ Class class_ = classes[i];
canonicalName.getChild(class_.name).bindTo(class_.reference);
class_.computeCanonicalNames();
}
@@ -878,16 +882,20 @@
void computeCanonicalNames() {
assert(canonicalName != null);
- for (var member in fields) {
+ for (int i = 0; i < fields.length; ++i) {
+ Field member = fields[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
}
- for (var member in procedures) {
+ for (int i = 0; i < procedures.length; ++i) {
+ Procedure member = procedures[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
}
- for (var member in constructors) {
+ for (int i = 0; i < constructors.length; ++i) {
+ Constructor member = constructors[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
}
- for (var member in redirectingFactoryConstructors) {
+ for (int i = 0; i < redirectingFactoryConstructors.length; ++i) {
+ RedirectingFactoryConstructor member = redirectingFactoryConstructors[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
}
}
@@ -5450,8 +5458,8 @@
}
void computeCanonicalNames() {
- for (var library in libraries) {
- computeCanonicalNamesForLibrary(library);
+ for (int i = 0; i < libraries.length; ++i) {
+ computeCanonicalNamesForLibrary(libraries[i]);
}
}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index c4cc243..56152ba 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -493,40 +493,44 @@
}
void _checkCanonicalNameChildren(CanonicalName parent) {
- for (CanonicalName child in parent.children) {
- if (child.name != '@methods' &&
- child.name != '@typedefs' &&
- child.name != '@fields' &&
- child.name != '@getters' &&
- child.name != '@setters' &&
- child.name != '@factories' &&
- child.name != '@constructors') {
- bool checkReferenceNode = true;
- if (child.reference == null) {
- // OK for "if private: URI of library" part of "Qualified name"...
- Iterable<CanonicalName> children = child.children;
- if (parent.parent != null &&
- children.isNotEmpty &&
- children.first.name.startsWith("_")) {
- // OK then.
- checkReferenceNode = false;
- } else {
- throw new CanonicalNameError(
- "Null reference (${child.name}) ($child).");
+ Iterable<CanonicalName> parentChildren = parent.childrenOrNull;
+ if (parentChildren != null) {
+ for (CanonicalName child in parentChildren) {
+ if (child.name != '@methods' &&
+ child.name != '@typedefs' &&
+ child.name != '@fields' &&
+ child.name != '@getters' &&
+ child.name != '@setters' &&
+ child.name != '@factories' &&
+ child.name != '@constructors') {
+ bool checkReferenceNode = true;
+ if (child.reference == null) {
+ // OK for "if private: URI of library" part of "Qualified name"...
+ Iterable<CanonicalName> children = child.childrenOrNull;
+ if (parent.parent != null &&
+ children != null &&
+ children.isNotEmpty &&
+ children.first.name.startsWith("_")) {
+ // OK then.
+ checkReferenceNode = false;
+ } else {
+ throw new CanonicalNameError(
+ "Null reference (${child.name}) ($child).");
+ }
+ }
+ if (checkReferenceNode) {
+ if (child.reference.canonicalName != child) {
+ throw new CanonicalNameError(
+ "Canonical name and reference doesn't agree.");
+ }
+ if (child.reference.node == null) {
+ throw new CanonicalNameError(
+ "Reference is null (${child.name}) ($child).");
+ }
}
}
- if (checkReferenceNode) {
- if (child.reference.canonicalName != child) {
- throw new CanonicalNameError(
- "Canonical name and reference doesn't agree.");
- }
- if (child.reference.node == null) {
- throw new CanonicalNameError(
- "Reference is null (${child.name}) ($child).");
- }
- }
+ _checkCanonicalNameChildren(child);
}
- _checkCanonicalNameChildren(child);
}
}
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 68e8f28..cd3edbe 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -269,13 +269,15 @@
void writeList<T>(List<T> items, void writeItem(T x)) {
writeUInt30(items.length);
- items.forEach(writeItem);
+ for (int i = 0; i < items.length; ++i) {
+ writeItem(items[i]);
+ }
}
void writeNodeList(List<Node> nodes) {
final len = nodes.length;
writeUInt30(len);
- for (var i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
final node = nodes[i];
writeNode(node);
}
@@ -313,19 +315,25 @@
void indexLinkTable(Component component) {
_canonicalNameList = <CanonicalName>[];
- void visitCanonicalName(CanonicalName node) {
- node.index = _canonicalNameList.length;
- _canonicalNameList.add(node);
- node.children.forEach(visitCanonicalName);
- }
-
- for (var library in component.libraries) {
+ for (int i = 0; i < component.libraries.length; ++i) {
+ Library library = component.libraries[i];
if (!shouldWriteLibraryCanonicalNames(library)) continue;
- visitCanonicalName(library.canonicalName);
+ _indexLinkTableInternal(library.canonicalName);
_knownCanonicalNameNonRootTops.add(library.canonicalName);
}
}
+ void _indexLinkTableInternal(CanonicalName node) {
+ node.index = _canonicalNameList.length;
+ _canonicalNameList.add(node);
+ Iterable<CanonicalName> children = node.childrenOrNull;
+ if (children != null) {
+ for (CanonicalName child in children) {
+ _indexLinkTableInternal(child);
+ }
+ }
+ }
+
/// Compute canonical names for the whole component or parts of it.
void computeCanonicalNames(Component component) {
component.computeCanonicalNames();
@@ -338,7 +346,7 @@
bool shouldWriteLibraryCanonicalNames(Library library) => true;
void writeCanonicalNameEntry(CanonicalName node) {
- var parent = node.parent;
+ CanonicalName parent = node.parent;
if (parent.isRoot) {
writeUInt30(0);
} else {
@@ -391,7 +399,7 @@
}
void _writeNodeMetadataImpl(Node node, int nodeOffset) {
- for (var subsection in _metadataSubsections) {
+ for (_MetadataSubsection subsection in _metadataSubsections) {
final repository = subsection.repository;
final value = repository.mapping[node];
if (value == null) {
@@ -473,13 +481,13 @@
// RList<MetadataMapping> metadataMappings
_binaryOffsetForMetadataMappings = getBufferOffset();
- for (var subsection in _metadataSubsections) {
+ for (_MetadataSubsection subsection in _metadataSubsections) {
// UInt32 tag
writeUInt32(stringIndexer.put(subsection.repository.tag));
// RList<Pair<UInt32, UInt32>> nodeOffsetToMetadataOffset
final mappingLength = subsection.metadataMapping.length;
- for (var i = 0; i < mappingLength; i += 2) {
+ for (int i = 0; i < mappingLength; i += 2) {
writeUInt32(subsection.metadataMapping[i]); // node offset
writeUInt32(subsection.metadataMapping[i + 1]); // metadata offset
}
@@ -490,7 +498,9 @@
/// Write all of some of the libraries of the [component].
void writeLibraries(Component component) {
- component.libraries.forEach(writeNode);
+ for (int i = 0; i < component.libraries.length; ++i) {
+ writeNode(component.libraries[i]);
+ }
}
void writeComponentIndex(Component component, List<Library> libraries) {
@@ -565,10 +575,11 @@
List<int> lineStarts = source.lineStarts;
writeUInt30(lineStarts.length);
int previousLineStart = 0;
- lineStarts.forEach((lineStart) {
+ for (int j = 0; j < lineStarts.length; ++j) {
+ int lineStart = lineStarts[j];
writeUInt30(lineStart - previousLineStart);
previousLineStart = lineStart;
- });
+ }
i++;
}
@@ -674,23 +685,25 @@
leaveScope(memberScope: true);
writeNodeList(node.typedefs);
- classOffsets = <int>[];
+ classOffsets = new List<int>();
writeNodeList(node.classes);
classOffsets.add(getBufferOffset());
writeNodeList(node.fields);
- procedureOffsets = <int>[];
+ procedureOffsets = new List<int>();
writeNodeList(node.procedures);
procedureOffsets.add(getBufferOffset());
// Fixed-size ints at the end used as an index.
assert(classOffsets.length > 0);
- for (int offset in classOffsets) {
+ for (int i = 0; i < classOffsets.length; ++i) {
+ int offset = classOffsets[i];
writeUInt32(offset);
}
writeUInt32(classOffsets.length - 1);
assert(procedureOffsets.length > 0);
- for (int offset in procedureOffsets) {
+ for (int i = 0; i < procedureOffsets.length; ++i) {
+ int offset = procedureOffsets[i];
writeUInt32(offset);
}
writeUInt32(procedureOffsets.length - 1);
@@ -702,7 +715,7 @@
: <LibraryDependency, int>{};
writeUInt30(library.dependencies.length);
for (int i = 0; i < library.dependencies.length; ++i) {
- var importNode = library.dependencies[i];
+ LibraryDependency importNode = library.dependencies[i];
_libraryDependencyIndex[importNode] = i;
writeLibraryDependency(importNode);
}
@@ -735,7 +748,7 @@
void writeLibraryParts(Library library) {
writeUInt30(library.parts.length);
for (int i = 0; i < library.parts.length; ++i) {
- var partNode = library.parts[i];
+ LibraryPart partNode = library.parts[i];
writeLibraryPart(partNode);
}
}
@@ -777,7 +790,7 @@
void writeAnnotationList(List<Expression> annotations) {
final len = annotations.length;
writeUInt30(len);
- for (var i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
final annotation = annotations[i];
writeAnnotation(annotation);
}
@@ -827,7 +840,8 @@
leaveScope(typeParameters: node.typeParameters);
assert(procedureOffsets.length > 0);
- for (int offset in procedureOffsets) {
+ for (int i = 0; i < procedureOffsets.length; ++i) {
+ int offset = procedureOffsets[i];
writeUInt32(offset);
}
writeUInt32(procedureOffsets.length - 1);
@@ -1000,9 +1014,9 @@
void visitFunctionNode(FunctionNode node) {
writeByte(Tag.FunctionNode);
enterScope(typeParameters: node.typeParameters, variableScope: true);
- var oldLabels = _labelIndexer;
+ LabelIndexer oldLabels = _labelIndexer;
_labelIndexer = null;
- var oldCases = _switchCaseIndexer;
+ SwitchCaseIndexer oldCases = _switchCaseIndexer;
_switchCaseIndexer = null;
// Note: FunctionNode has no tag.
writeOffset(node.fileOffset);
@@ -1990,7 +2004,7 @@
}
void pushScope() {
- scopes ??= <int>[];
+ scopes ??= new List<int>();
scopes.add(stackHeight);
}
@@ -2027,7 +2041,7 @@
int stackHeight = 0;
void enter(SwitchStatement node) {
- for (var caseNode in node.cases) {
+ for (SwitchCase caseNode in node.cases) {
index[caseNode] = stackHeight++;
}
}
@@ -2089,7 +2103,8 @@
int stackHeight = 0;
void enter(List<TypeParameter> typeParameters) {
- for (var parameter in typeParameters) {
+ for (int i = 0; i < typeParameters.length; ++i) {
+ TypeParameter parameter = typeParameters[i];
index[parameter] = stackHeight;
++stackHeight;
}
@@ -2097,7 +2112,9 @@
void exit(List<TypeParameter> typeParameters) {
stackHeight -= typeParameters.length;
- typeParameters.forEach(index.remove);
+ for (int i = 0; i < typeParameters.length; ++i) {
+ index.remove(typeParameters[i]);
+ }
}
int operator [](TypeParameter parameter) =>
@@ -2113,7 +2130,7 @@
}
int put(String string) {
- var result = index[string];
+ int result = index[string];
if (result == null) {
result = index.length;
index[string] = result;
@@ -2133,7 +2150,7 @@
}
int put(Uri uri) {
- var result = index[uri];
+ int result = index[uri];
if (result == null) {
result = index.length;
index[uri] = result;
@@ -2289,8 +2306,8 @@
RangeError.checkValidIndex(index, target, null, target.length);
end = RangeError.checkValidRange(start, end, source.length);
if (start == end) return index;
- var i = start;
- var length = target.length;
+ int i = start;
+ int length = target.length;
do {
int codeUnit = source.codeUnitAt(i++);
while (codeUnit < 128) {
diff --git a/pkg/kernel/lib/binary/limited_ast_to_binary.dart b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
index bd00832..0b7d088 100644
--- a/pkg/kernel/lib/binary/limited_ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
@@ -43,10 +43,11 @@
return predicate(library);
}
- @override
void writeLibraries(Component component) {
- var librariesToWrite = component.libraries.where(predicate).toList();
- writeList(librariesToWrite, writeNode);
+ for (int i = 0; i < component.libraries.length; ++i) {
+ Library library = component.libraries[i];
+ if (predicate(library)) writeNode(library);
+ }
}
@override
diff --git a/pkg/kernel/lib/canonical_name.dart b/pkg/kernel/lib/canonical_name.dart
index 6fbc693..20bf36c 100644
--- a/pkg/kernel/lib/canonical_name.dart
+++ b/pkg/kernel/lib/canonical_name.dart
@@ -94,6 +94,8 @@
Iterable<CanonicalName> get children =>
_children?.values ?? const <CanonicalName>[];
+ Iterable<CanonicalName> get childrenOrNull => _children?.values;
+
bool hasChild(String name) {
return _children != null && _children.containsKey(name);
}
@@ -175,8 +177,11 @@
void unbindAll() {
unbind();
- for (var child in children) {
- child.unbindAll();
+ Iterable<CanonicalName> children_ = childrenOrNull;
+ if (children_ != null) {
+ for (CanonicalName child in children_) {
+ child.unbindAll();
+ }
}
}