Skip to content

Commit

Permalink
perf(#21): preallocate filtered candidate buffers
Browse files Browse the repository at this point in the history
This has two benefits:
1. Because zf uses an arena allocator and does not deallocate, this
   prevents extra allocations and zf no longer uses more memory the
   longer the program runs.
2. There also seems to be a slight performance improvement by
   preallocating, which makes sense.

Closes #21
  • Loading branch information
natecraddock committed Feb 10, 2023
1 parent 75d5bc1 commit c2a36ba
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 14 deletions.
25 changes: 13 additions & 12 deletions src/filter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -76,33 +76,33 @@ test "collectCandidates excess whitespace" {
/// returns a sorted slice of Candidates that match the query ready for display
/// in a tui or output to stdout
pub fn rankCandidates(
allocator: std.mem.Allocator,
ranked: []Candidate,
candidates: []const []const u8,
tokens: []const []const u8,
keep_order: bool,
plain: bool,
case_sensitive: bool,
) ![]Candidate {
var ranked = ArrayList(Candidate).init(allocator);

) []Candidate {
if (tokens.len == 0) {
for (candidates) |candidate| {
try ranked.append(.{ .str = candidate });
for (candidates) |candidate, index| {
ranked[index] = .{ .str = candidate };
}
return ranked.toOwnedSlice();
return ranked;
}

var index: usize = 0;
for (candidates) |candidate| {
if (rankCandidate(candidate, tokens, case_sensitive, plain)) |rank| {
try ranked.append(.{ .str = candidate, .rank = rank });
ranked[index] = .{ .str = candidate, .rank = rank };
index += 1;
}
}

if (!keep_order) {
std.sort.sort(Candidate, ranked.items, {}, sort);
std.sort.sort(Candidate, ranked[0..index], {}, sort);
}

return ranked.toOwnedSlice();
return ranked[0..index];
}

const indexOfCaseSensitive = std.mem.indexOfScalarPos;
Expand Down Expand Up @@ -369,8 +369,9 @@ fn testRankCandidates(
candidates: []const []const u8,
expected: []const []const u8,
) !void {
const ranked = try rankCandidates(testing.allocator, candidates, tokens, false, false, false);
defer testing.allocator.free(ranked);
var ranked_buf = try testing.allocator.alloc(Candidate, candidates.len);
defer testing.allocator.free(ranked_buf);
const ranked = rankCandidates(ranked_buf, candidates, tokens, false, false, false);

for (expected) |expected_str, i| {
if (!std.mem.eql(u8, expected_str, ranked[i].str)) {
Expand Down
3 changes: 2 additions & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ pub fn main() anyerror!void {
var tokens_buf = try allocator.alloc([]const u8, 16);
const tokens = ui.splitQuery(tokens_buf, config.query);
const case_sensitive = ui.hasUpper(config.query);
const filtered = try filter.rankCandidates(allocator, candidates, tokens, config.keep_order, config.plain, case_sensitive);
var filtered_buf = try allocator.alloc(filter.Candidate, candidates.len);
const filtered = filter.rankCandidates(filtered_buf, candidates, tokens, config.keep_order, config.plain, case_sensitive);
if (filtered.len == 0) std.process.exit(1);
for (filtered) |candidate| {
try stdout.print("{s}\n", .{candidate.str});
Expand Down
4 changes: 3 additions & 1 deletion src/ui.zig
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ pub fn run(
var tokens: [][]const u8 = splitQuery(tokens_buf, query.slice());
var case_sensitive: bool = hasUpper(query.slice());

var filtered_buf = try allocator.alloc(Candidate, candidates.len);

var redraw = true;

while (true) {
Expand All @@ -359,7 +361,7 @@ pub fn run(
tokens = splitQuery(tokens_buf, (try normalizer.nfd(allocator, query.slice())).slice);
case_sensitive = hasUpper(query.slice());

filtered = try filter.rankCandidates(allocator, candidates, tokens, keep_order, plain, case_sensitive);
filtered = filter.rankCandidates(filtered_buf, candidates, tokens, keep_order, plain, case_sensitive);
redraw = true;
state.selected = 0;
}
Expand Down

0 comments on commit c2a36ba

Please sign in to comment.