aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hash_map.zig40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/hash_map.zig b/src/hash_map.zig
index 18583f378..69c56997c 100644
--- a/src/hash_map.zig
+++ b/src/hash_map.zig
@@ -12,7 +12,7 @@ const mem = std.mem;
const meta = std.meta;
const trait = meta.trait;
const Allocator = mem.Allocator;
-const Wyhash = std.hash.Wyhash;
+const Wyhash = @import("./Wyhash.zig").Wyhash;
pub fn getAutoHashFn(comptime K: type) (fn (K) u64) {
comptime {
@@ -39,7 +39,12 @@ pub fn getAutoHashFn(comptime K: type) (fn (K) u64) {
}.hash;
}
+const autoEqlTrait = std.meta.trait.hasFn("eql");
pub fn getAutoEqlFn(comptime K: type) (fn (K, K) bool) {
+ if (comptime autoEqlTrait(K)) {
+ return @field(K, "eql");
+ }
+
return struct {
fn eql(a: K, b: K) bool {
return meta.eql(a, b);
@@ -64,6 +69,18 @@ pub fn StringHashMapUnmanaged(comptime V: type) type {
return HashMapUnmanaged([]const u8, V, hashString, eqlString, default_max_load_percentage);
}
+// ❯ hyperfine "./esdev.stringEqlNoPtrCheck --resolve=dev --cwd /Users/jarred/Code/esdev/bench/rome/src entry --platform=node --outdir=/Users/jarred/Code/esdev/bench/rome/src/out --public-url=https://hello.com/" "./esdev-fd-rel-hash --resolve=dev --cwd /Users/jarred/Code/esdev/bench/rome/src entry --platform=node --outdir=/Users/jarred/Code/esdev/bench/rome/src/out --public-url=https://hello.com/" --min-runs=50
+// Benchmark #1: ./esdev.stringEqlNoPtrCheck --resolve=dev --cwd /Users/jarred/Code/esdev/bench/rome/src entry --platform=node --outdir=/Users/jarred/Code/esdev/bench/rome/src/out --public-url=https://hello.com/
+// Time (mean ± σ): 251.5 ms ± 7.8 ms [User: 110.0 ms, System: 135.7 ms]
+// Range (min … max): 239.0 ms … 281.1 ms 50 runs
+
+// Benchmark #2: ./esdev-fd-rel-hash --resolve=dev --cwd /Users/jarred/Code/esdev/bench/rome/src entry --platform=node --outdir=/Users/jarred/Code/esdev/bench/rome/src/out --public-url=https://hello.com/
+// Time (mean ± σ): 249.3 ms ± 8.3 ms [User: 110.8 ms, System: 134.0 ms]
+// Range (min … max): 239.8 ms … 288.7 ms 50 runs
+
+// Summary
+// './esdev-fd-rel-hash --resolve=dev --cwd /Users/jarred/Code/esdev/bench/rome/src entry --platform=node --outdir=/Users/jarred/Code/esdev/bench/rome/src/out --public-url=https://hello.com/' ran
+// 1.01 ± 0.05 times faster than './esdev.stringEqlNoPtrCheck --resolve=dev --cwd /Users/jarred/Code/esdev/bench/rome/src entry --platform=node --outdir=/Users/jarred/Code/esdev/bench/rome/src/out --public-url=https://hello.com/'
pub fn eqlString(a: []const u8, b: []const u8) bool {
return mem.eql(u8, a, b);
}
@@ -134,7 +151,7 @@ pub fn HashMap(
}
/// Get an optional pointer to the value associated with key, if present.
- pub fn getHash(self: Self, key: K) u64 {
+ pub fn getHash(key: K) u64 {
return hashFn(key);
}
@@ -230,6 +247,10 @@ pub fn HashMap(
return self.unmanaged.getEntry(key);
}
+ pub fn getEntryWithHash(self: Self, key: K, hash: u64) ?*Entry {
+ return self.unmanaged.getEntryWithHash(key, hash);
+ }
+
pub fn contains(self: Self, key: K) bool {
return self.unmanaged.contains(key);
}
@@ -550,12 +571,15 @@ pub fn HashMapUnmanaged(
return result;
}
- pub fn getEntry(self: Self, key: K) ?*Entry {
+ pub fn getEntryWithHash(self: Self, key: K, hash: u64) ?*Entry {
if (self.size == 0) {
return null;
}
- const hash = hashFn(key);
+ return @call(.{ .modifier = .always_inline }, _getEntryWithHash, .{ self, key, hash });
+ }
+
+ fn _getEntryWithHash(self: Self, key: K, hash: u64) ?*Entry {
const mask = self.capacity() - 1;
const fingerprint = Metadata.takeFingerprint(hash);
var idx = @truncate(usize, hash & mask);
@@ -575,6 +599,14 @@ pub fn HashMapUnmanaged(
return null;
}
+ pub fn getEntry(self: Self, key: K) ?*Entry {
+ if (self.size == 0) {
+ return null;
+ }
+
+ return @call(.{ .modifier = .always_inline }, _getEntryWithHash, .{ self, key, hashFn(key) });
+ }
+
/// Insert an entry if the associated key is not already present, otherwise update preexisting value.
pub fn put(self: *Self, allocator: *Allocator, key: K, value: V) !void {
const result = try self.getOrPut(allocator, key);