mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
A couple significant performance improvements for styles (#3097)
To preface, I tested the impact of these changes by running DOOM-fire-zig in a 120x30 window on a ReleaseFast build. I feel that DOOM-fire-zig is a fairly realistic target when it comes to "high style use" terminal applications. 1. By adjusting the conditions under which we swap items while inserting in to our hash table in `RefCountedSet` we can prioritize styles with many refs, so they're more likely to stay near their target bucket. This change brought DFZ FPS from ~700 to ~840, or a roughly 20% improvement. 2. By changing how we hash `Style` structs, we can avoid a lot of unnecessary overhead and benefit from smaller i-cache size as well as xxHash's better statistical qualities when compared to Wyhash. This change brought DFZ FPS from ~840 to ~1020, or another roughly 20% improvement. These two changes combined represent as roughly 45% improvement over `main`, which is... pretty good I'd say. In addition, I've run `vtebench` and there is no significant difference in the results between this PR and main.
This commit is contained in:
@ -607,8 +607,16 @@ pub fn RefCountedSet(
|
||||
break;
|
||||
}
|
||||
|
||||
// This item has a lower PSL, swap it out with our held item.
|
||||
if (item.meta.psl < held_item.meta.psl) {
|
||||
// If this item has a lower PSL, or has equal PSL and lower ref
|
||||
// count, then we swap it out with our held item. By doing this,
|
||||
// items with high reference counts are prioritized for earlier
|
||||
// placement. The assumption is that an item which has a higher
|
||||
// reference count will be accessed more frequently, so we want
|
||||
// to minimize the time it takes to find it.
|
||||
if (item.meta.psl < held_item.meta.psl or
|
||||
item.meta.psl == held_item.meta.psl and
|
||||
item.meta.ref < held_item.meta.ref)
|
||||
{
|
||||
// Put our held item in the bucket.
|
||||
table[p] = held_id;
|
||||
held_item.meta.bucket = p;
|
||||
|
@ -8,8 +8,7 @@ const Offset = size.Offset;
|
||||
const OffsetBuf = size.OffsetBuf;
|
||||
const RefCountedSet = @import("ref_counted_set.zig").RefCountedSet;
|
||||
|
||||
const Wyhash = std.hash.Wyhash;
|
||||
const autoHash = std.hash.autoHash;
|
||||
const XxHash3 = std.hash.XxHash3;
|
||||
|
||||
/// The unique identifier for a style. This is at most the number of cells
|
||||
/// that can fit into a terminal page.
|
||||
@ -230,10 +229,13 @@ pub const Style = struct {
|
||||
_ = try writer.write(" }");
|
||||
}
|
||||
|
||||
/// Hash the raw bytes of the struct with XxHash3
|
||||
///
|
||||
/// NOTE: Because the struct does not have a guaranteed in-memory layout
|
||||
/// this hash is NOT suitable for serialization. If used for a hash
|
||||
/// table that is then serialized, it MUST be re-hashed when read.
|
||||
pub fn hash(self: *const Style) u64 {
|
||||
var hasher = Wyhash.init(0);
|
||||
autoHash(&hasher, self.*);
|
||||
return hasher.final();
|
||||
return XxHash3.hash(0, @as(*const [@sizeOf(Style)]u8, @ptrCast(self)));
|
||||
}
|
||||
|
||||
test {
|
||||
|
Reference in New Issue
Block a user