From 55181912175a54cdee246785ac8dd17d9f756838 Mon Sep 17 00:00:00 2001 From: Nuno Mendes <98030270+nm-remarkable@users.noreply.github.com> Date: Sun, 29 Sep 2024 17:57:29 +0200 Subject: [PATCH] std.fs.File: use file size as ArrayList initial capacity --- lib/compiler/fmt.zig | 2 +- lib/std/fs/File.zig | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/compiler/fmt.zig b/lib/compiler/fmt.zig index c747addd72aa..a644394ba7d8 100644 --- a/lib/compiler/fmt.zig +++ b/lib/compiler/fmt.zig @@ -276,7 +276,7 @@ fn fmtPathFile( const source_code = try std.zig.readSourceFileToEndAlloc( gpa, source_file, - std.math.cast(usize, stat.size) orelse return error.FileTooBig, + null, ); defer gpa.free(source_code); diff --git a/lib/std/fs/File.zig b/lib/std/fs/File.zig index 36e7999bf79d..d302cc619229 100644 --- a/lib/std/fs/File.zig +++ b/lib/std/fs/File.zig @@ -1149,13 +1149,24 @@ pub fn readToEndAllocOptions( comptime alignment: u29, comptime optional_sentinel: ?u8, ) !(if (optional_sentinel) |s| [:s]align(alignment) u8 else []align(alignment) u8) { - // If no size hint is provided fall back to the size=0 code path - const size = size_hint orelse 0; - // The file size returned by stat is used as hint to set the buffer - // size. If the reported size is zero, as it happens on Linux for files - // in /proc, a small buffer is allocated instead. - const initial_cap = (if (size > 0) size else 1024) + @intFromBool(optional_sentinel != null); + var size: usize = undefined; + if (size_hint) |hint| { + size = hint; + } else { + // If no size hint is provided the file size returned by stat() is used as a + // hint to set the buffer size. + const file_stat = self.stat(); + if (file_stat) |value| { + size = std.math.cast(usize, value.size) orelse return error.FileTooBig; + } else |_| { + // If the reported size is zero or there was an error reading stat(), + // for example on Linux for files in /proc, a small buffer is allocated instead. + size = 1024; + } + } + + const initial_cap = size + @intFromBool(optional_sentinel != null); var array_list = try std.ArrayListAligned(u8, alignment).initCapacity(allocator, initial_cap); defer array_list.deinit();