mirror of
https://github.com/ziglang/zig.git
synced 2026-01-04 12:33:19 +00:00
zig fmt: avoid unnecessary file system access
zig fmt previously would write a temp file, and then either rename it into place if necessary, or unlink it if nothing was changed. Now zig fmt renders into a memory buffer, and only writes the temp file and renames it into place if anything changed. Based on the performance testing I did this actually did not have much of an impact, however it's likely that on other operating systems and other hard drives this could make a big difference.
This commit is contained in:
parent
0a9672fb86
commit
64dfd1883e
@ -546,6 +546,7 @@ const Fmt = struct {
|
||||
any_error: bool,
|
||||
color: Color,
|
||||
gpa: *Allocator,
|
||||
out_buffer: std.ArrayList(u8),
|
||||
|
||||
const SeenMap = std.AutoHashMap(fs.File.INode, void);
|
||||
};
|
||||
@ -641,7 +642,10 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
|
||||
.seen = Fmt.SeenMap.init(gpa),
|
||||
.any_error = false,
|
||||
.color = color,
|
||||
.out_buffer = std.ArrayList(u8).init(gpa),
|
||||
};
|
||||
defer fmt.seen.deinit();
|
||||
defer fmt.out_buffer.deinit();
|
||||
|
||||
for (input_files.span()) |file_path| {
|
||||
// Get the real path here to avoid Windows failing on relative file paths with . or .. in them.
|
||||
@ -767,14 +771,19 @@ fn fmtPathFile(
|
||||
fmt.any_error = true;
|
||||
}
|
||||
} else {
|
||||
const baf = try io.BufferedAtomicFile.create(fmt.gpa, dir, sub_path, .{ .mode = stat.mode });
|
||||
defer baf.destroy();
|
||||
// As a heuristic, we make enough capacity for the same as the input source.
|
||||
try fmt.out_buffer.ensureCapacity(source_code.len);
|
||||
fmt.out_buffer.items.len = 0;
|
||||
const anything_changed = try std.zig.render(fmt.gpa, fmt.out_buffer.writer(), tree);
|
||||
if (!anything_changed)
|
||||
return; // Good thing we didn't waste any file system access on this.
|
||||
|
||||
const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree);
|
||||
if (anything_changed) {
|
||||
std.debug.warn("{}\n", .{file_path});
|
||||
try baf.finish();
|
||||
}
|
||||
var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode });
|
||||
defer af.deinit();
|
||||
|
||||
try af.file.writeAll(fmt.out_buffer.items);
|
||||
try af.finish();
|
||||
std.debug.warn("{}\n", .{file_path});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user