Skip to content

Use explicit keys for often accessed closures #1591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1560,8 +1560,8 @@ abstract class GetterSetterCombo implements ModelElement {
if (targetClass.name == target.name) {
return original.replaceAll(constructorName, "${target.linkedName}");
}
return original.replaceAll(
"${targetClass.name}.${target.name}", "${targetClass.linkedName}.${target.linkedName}");
return original.replaceAll("${targetClass.name}.${target.name}",
"${targetClass.linkedName}.${target.linkedName}");
}

String _constantValueBase() {
Expand Down Expand Up @@ -2892,7 +2892,8 @@ abstract class ModelElement extends Canonicalization
///
/// For example: libraryName.className.methodName
@override
String get fullyQualifiedName => _memoizer.memoized(_buildFullyQualifiedName);
String get fullyQualifiedName => _memoizer.memoized(_buildFullyQualifiedName,
altKey: 'fullyQualifiedName');

String _fullyQualifiedNameWithoutLibrary() {
// Remember, periods are legal in library names.
Expand All @@ -2904,7 +2905,8 @@ abstract class ModelElement extends Canonicalization
// library.fullyQualifiedName seems somehow to break things.
//String get fullyQualifiedNameWithoutLibrary => _memoizer.memoized2(fullyQualifiedName.replaceFirst, "${library.fullyQualifiedName}.", '');
String get fullyQualifiedNameWithoutLibrary =>
_memoizer.memoized(_fullyQualifiedNameWithoutLibrary);
_memoizer.memoized(_fullyQualifiedNameWithoutLibrary,
altKey: 'fullyQualifiedNameWithoutLibrary');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is hashing a string really noticeably faster than hashing a tearoff method?


String get sourceFileName => element.source.fullName;

Expand Down
23 changes: 13 additions & 10 deletions lib/src/model_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,17 @@ String crossdartifySource(

/// An UnmodifiableListView that computes equality and hashCode based on the
/// equality and hashCode of its contained objects.
class _HashableList extends UnmodifiableListView<dynamic> {
_HashableList(Iterable<dynamic> iterable) : super(iterable);
class _HashableList {
final List _source;
int _hashCache;
_HashableList(this._source);

@override
bool operator ==(other) {
if (other is _HashableList) {
if (this.length == other.length) {
for (var index = 0; index < length; ++index) {
if (this[index] != other[index]) return false;
if (_source.length == other._source.length) {
for (var index = 0; index < _source.length; ++index) {
if (_source[index] != other._source[index]) return false;
}
return true;
}
Expand All @@ -189,7 +191,7 @@ class _HashableList extends UnmodifiableListView<dynamic> {
}

@override
get hashCode => hashObjects(this);
get hashCode => _hashCache ??= hashObjects(_source);
}

/// Like [Memoizer], except in checked mode will validate that the value of the
Expand Down Expand Up @@ -252,11 +254,11 @@ class ValidatingMemoizer extends Memoizer {
/// ```
class Memoizer {
/// Map of a function and its positional parameters (if any), to a value.
Map<_HashableList, dynamic> _memoizationTable = new Map();
final Map<_HashableList, dynamic> _memoizationTable = new HashMap();

/// Reset the memoization table, forcing calls of the underlying functions.
void invalidateMemos() {
_memoizationTable = new Map();
_memoizationTable.clear();
}

/// A wrapper around putIfAbsent, exposed to allow overrides.
Expand All @@ -266,8 +268,9 @@ class Memoizer {

/// Calls and caches the return value of [f]() if not in the cache, then
/// returns the cached value of [f]().
R memoized<R>(Function f) {
_HashableList key = new _HashableList([f]);
R memoized<R>(Function f, {String altKey}) {
Object obj = altKey ?? f;
_HashableList key = new _HashableList([obj]);
return _cacheIfAbsent(key, f);
}

Expand Down