mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 08:16:13 +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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This item has a lower PSL, swap it out with our held item.
|
// If this item has a lower PSL, or has equal PSL and lower ref
|
||||||
if (item.meta.psl < held_item.meta.psl) {
|
// 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.
|
// Put our held item in the bucket.
|
||||||
table[p] = held_id;
|
table[p] = held_id;
|
||||||
held_item.meta.bucket = p;
|
held_item.meta.bucket = p;
|
||||||
|
@ -8,8 +8,7 @@ const Offset = size.Offset;
|
|||||||
const OffsetBuf = size.OffsetBuf;
|
const OffsetBuf = size.OffsetBuf;
|
||||||
const RefCountedSet = @import("ref_counted_set.zig").RefCountedSet;
|
const RefCountedSet = @import("ref_counted_set.zig").RefCountedSet;
|
||||||
|
|
||||||
const Wyhash = std.hash.Wyhash;
|
const XxHash3 = std.hash.XxHash3;
|
||||||
const autoHash = std.hash.autoHash;
|
|
||||||
|
|
||||||
/// The unique identifier for a style. This is at most the number of cells
|
/// The unique identifier for a style. This is at most the number of cells
|
||||||
/// that can fit into a terminal page.
|
/// that can fit into a terminal page.
|
||||||
@ -230,10 +229,13 @@ pub const Style = struct {
|
|||||||
_ = try writer.write(" }");
|
_ = 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 {
|
pub fn hash(self: *const Style) u64 {
|
||||||
var hasher = Wyhash.init(0);
|
return XxHash3.hash(0, @as(*const [@sizeOf(Style)]u8, @ptrCast(self)));
|
||||||
autoHash(&hasher, self.*);
|
|
||||||
return hasher.final();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
Reference in New Issue
Block a user