zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 64dfd1883eb2b9ab175af9b07c84bd4b53b7e904 (tree)
parent 0a9672fb86b84658f8780f57e769be45e41f3034
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Sat, 20 Jun 2020 20:14:33 -0400

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.

Diffstat:
Msrc-self-hosted/main.zig | 25+++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig @@ -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(); - - const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree); - if (anything_changed) { - std.debug.warn("{}\n", .{file_path}); - try baf.finish(); - } + // 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. + + 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}); } }