mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std: hash_map: optimize isFree/isTombstone (#10562)
- Add an `Metadata.isFree` helper method. - Implement `Metadata.isTombstone` and `Metadata.isFree` with `@bitCast` then comparing to a constant. I assume `@bitCast`-then-compare is faster than the old method because it only involves one comparison, and doesn't require bitmasking. - Summary of benchmarked changes (`gotta-go-fast`, run locally, compared to master): - 3/4 of the hash map benchmarks used ~10% fewer cycles - The last one (project Euler) shows 4% fewer cycles.
This commit is contained in:
parent
ada8e17137
commit
4731a6e5d5
1 changed files with 10 additions and 3 deletions
|
|
@ -750,12 +750,19 @@ pub fn HashMapUnmanaged(
|
|||
fingerprint: FingerPrint = free,
|
||||
used: u1 = 0,
|
||||
|
||||
const slot_free = @bitCast(u8, Metadata{ .fingerprint = free });
|
||||
const slot_tombstone = @bitCast(u8, Metadata{ .fingerprint = tombstone });
|
||||
|
||||
pub fn isUsed(self: Metadata) bool {
|
||||
return self.used == 1;
|
||||
}
|
||||
|
||||
pub fn isTombstone(self: Metadata) bool {
|
||||
return !self.isUsed() and self.fingerprint == tombstone;
|
||||
return @bitCast(u8, self) == slot_tombstone;
|
||||
}
|
||||
|
||||
pub fn isFree(self: Metadata) bool {
|
||||
return @bitCast(u8, self) == slot_free;
|
||||
}
|
||||
|
||||
pub fn takeFingerprint(hash: Hash) FingerPrint {
|
||||
|
|
@ -1115,7 +1122,7 @@ pub fn HashMapUnmanaged(
|
|||
var idx = @truncate(usize, hash & mask);
|
||||
|
||||
var metadata = self.metadata.? + idx;
|
||||
while ((metadata[0].isUsed() or metadata[0].isTombstone()) and limit != 0) {
|
||||
while (!metadata[0].isFree() and limit != 0) {
|
||||
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
||||
const test_key = &self.keys()[idx];
|
||||
// If you get a compile error on this line, it means that your generic eql
|
||||
|
|
@ -1294,7 +1301,7 @@ pub fn HashMapUnmanaged(
|
|||
|
||||
var first_tombstone_idx: usize = self.capacity(); // invalid index
|
||||
var metadata = self.metadata.? + idx;
|
||||
while ((metadata[0].isUsed() or metadata[0].isTombstone()) and limit != 0) {
|
||||
while (!metadata[0].isFree() and limit != 0) {
|
||||
if (metadata[0].isUsed() and metadata[0].fingerprint == fingerprint) {
|
||||
const test_key = &self.keys()[idx];
|
||||
// If you get a compile error on this line, it means that your generic eql
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue