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
Investigate possibilities to improve performance of Object.hash()
#50693
Comments
/cc @lrhn @rakudrama |
As mentioned elsewhere, the goal should be to be as efficient as finalizeHash(combineHash(combineHash(0, a.hashCode), b.hashCode)) There should be a Providing a seed, instead of using The current implementation is shared between platforms. We could make all the public methods A platform could also choose to use a randomized seed in debug mode, to ensure that users do not end up relying on, say, a particular ordering of a hash map. In production mode, that value could be fixed, or even zero, instead. If we even consider using a different algorithm, then we should definitely make sure that we document that the hash value is not stable between executions. We've so far ensured that by using a random seed for user calls. The optional If it's a problem for the VM that someone might get access to the sentinel value used to detect the actual number of arguments passed, I wouldn't worry overly about it. If |
Issue #50693 Change-Id: Ib587b70bcb57cbd2d16319b7814e2569c7e41213 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276161 Commit-Queue: Lasse Nielsen <lrn@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
Aren't we assuming that any Users write code such as class Foo {
final a;
int get hashCode => a.hashCode;
bool operator(other) => identical(this, other) || other is Foo && a == other.a;
} Once they add a field, it changes to class Foo {
final a;
final b;
int get hashCode => Object.hash(a, b);
bool operator(other) => identical(this, other) || other is Foo && a == other.a && b == other.b;
} In fact Given the above, the assumption is that If the primitives in core library have well-distributed |
That's historically not been sound to assume. Consider a class like; class SomethingEntity {
static int _counter = 0;
// Each instance has a unique ID.
final int id = _counter++;
// More efficient than identityHashCode
int get hashCode => id;
// Still use identity for equality.
bool operator==(Object other);
} That seems as a safe and correct hash-code implementation, but it's not well-distributed. (I can see we've change a bunch of |
We should investigate whether we can improve the performance of our main corelib API for combining hashcodes, namely Object.hash.
Object.hash()
obj<X>.hashCode
calls on the callsite.=> a
Object.hash(a, b)
should be as efficient asfinalizeHash(combineHash(a.hashCode, b.hashCode))
=> Avoiding the bit-wise-and operations may speed it also up.
=> This may? also avoid overhead of the initial
combine(seed, obj1.hashCode)
.Ideally we'll end up in a core library API that we're willing to use ourselves in our code, e.g. replacing
Arguably some implementations want to call
combine
on a runtime-dependent number of objects and only callfinish
afterwards. That would make it hard to useObject.hash()
as an API (see e.g. fidl)./cc @aam
The text was updated successfully, but these errors were encountered: