mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-31 12:49:03 +00:00
terminal: reduce style hash mixing cost
Use the two-round SplitMix64 finalizer for the folded PackedStyle key. The previous std.hash.int u64 mixer performs three multiply rounds. Style hashing is paid for every real SGR transition, and the additional round did not improve lookup behavior for this key distribution. ReleaseFast timings are seven-run median user CPU times. | Workload | Before | After | Change | | --- | ---: | ---: | ---: | | 4,096 styles, live lookup | 0.87s | 0.83s | -4.6% | | Alternating SGR stream | 1.20s | 1.13s | -5.8% | | Truecolor SGR stream | 0.68s | 0.67s | -1.5% | | Clear/redraw SGR stream | 0.68s | 0.67s | -1.5% |
This commit is contained in:
@@ -530,11 +530,20 @@ pub const Style = struct {
|
||||
};
|
||||
|
||||
pub fn hash(self: *const Style) u64 {
|
||||
// We pack the style in to 128 bits, fold it to 64 bits,
|
||||
// then use std.hash.int to make it sufficiently uniform.
|
||||
// We pack the style in to 128 bits, fold it to 64 bits, then use the
|
||||
// SplitMix64 finalizer to make it sufficiently uniform:
|
||||
// https://prng.di.unimi.it/splitmix64.c
|
||||
//
|
||||
// This finalizer provides sufficient diffusion for the folded style
|
||||
// key with two multiply rounds. The u64 mixer used by std.hash.int
|
||||
// has three, and benchmarks show that extra round costs throughput on
|
||||
// this SGR hot path without improving style-set lookup performance.
|
||||
const packed_style: PackedStyle = .fromStyle(self.*);
|
||||
const wide: [2]u64 = @bitCast(packed_style);
|
||||
return @call(.always_inline, std.hash.int, .{wide[0] ^ wide[1]});
|
||||
var result = wide[0] ^ wide[1];
|
||||
result = (result ^ (result >> 30)) *% 0xbf58476d1ce4e5b9;
|
||||
result = (result ^ (result >> 27)) *% 0x94d049bb133111eb;
|
||||
return result ^ (result >> 31);
|
||||
}
|
||||
|
||||
comptime {
|
||||
|
||||
Reference in New Issue
Block a user