fix(perf): faster looseIdentical implementation
Remove String type check in looseIdentical in JS-mode. It is not necessary as dart2js already compiles `identical` to `===` which compares string contents. Inline call sites. This improves change detection of plain fields by 40%. On a large internal app the improvement is 5%. Closes #6364
This commit is contained in:
parent
3e65d1458e
commit
761c6d0df7
|
@ -235,10 +235,26 @@ class FunctionWrapper {
|
||||||
|
|
||||||
const _NAN_KEY = const Object();
|
const _NAN_KEY = const Object();
|
||||||
|
|
||||||
// Dart can have identical(str1, str2) == false while str1 == str2. Moreover,
|
// Dart VM implements `identical` as true reference identity. JavaScript does
|
||||||
// after compiling with dart2js identical(str1, str2) might return true.
|
// not have this. The closest we have in JS is `===`. However, for strings JS
|
||||||
// (see dartbug.com/22496 for details).
|
// would actually compare the contents rather than references. `dart2js`
|
||||||
bool looseIdentical(a, b) =>
|
// compiles `identical` to `===` and therefore there is a discrepancy between
|
||||||
|
// Dart VM and `dart2js`. The implementation of `looseIdentical` attempts to
|
||||||
|
// bridge the gap between the two while retaining good performance
|
||||||
|
// characteristics. In JS we use simple `identical`, which compiles to `===`,
|
||||||
|
// and in Dart VM we emulate the semantics of `===` by special-casing strings.
|
||||||
|
// Note that the VM check is a compile-time constant. This allows `dart2js` to
|
||||||
|
// evaluate the conditional during compilation and inline the entire function.
|
||||||
|
//
|
||||||
|
// See: dartbug.com/22496, dartbug.com/25270
|
||||||
|
const _IS_DART_VM = !identical(1.0, 1); // a hack
|
||||||
|
bool looseIdentical(a, b) => _IS_DART_VM
|
||||||
|
? _looseIdentical(a, b)
|
||||||
|
: identical(a, b);
|
||||||
|
|
||||||
|
// This function is intentionally separated from `looseIdentical` to keep the
|
||||||
|
// number of AST nodes low enough for `dart2js` to inline the code.
|
||||||
|
bool _looseIdentical(a, b) =>
|
||||||
a is String && b is String ? a == b : identical(a, b);
|
a is String && b is String ? a == b : identical(a, b);
|
||||||
|
|
||||||
// Dart compare map keys by equality and we can have NaN != NaN
|
// Dart compare map keys by equality and we can have NaN != NaN
|
||||||
|
@ -334,4 +350,4 @@ var global = null;
|
||||||
|
|
||||||
dynamic evalExpression(String sourceUrl, String expr, String declarations, Map<String, String> vars) {
|
dynamic evalExpression(String sourceUrl, String expr, String declarations, Map<String, String> vars) {
|
||||||
throw "Dart does not support evaluating expression during runtime!";
|
throw "Dart does not support evaluating expression during runtime!";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue