前面通过改写Rust程序输出缓冲功能为C实现了输出速度提升以后,想将同样的思路用在Zig程序上。
又来请DeepSeek改写,第一次改写,它杜撰了一个函数bufferedWriterSize函数,查阅文档发现,只有bufferedWriter函数,但此函数只有一个参数,size固定为4096。
pub fn bufferedWriter(underlying_stream: anytype) BufferedWriter(4096, @TypeOf(underlying_stream))
将bufferedWriterSize函数替换为正确的bufferedWriter,编译通过,但执行效率没有提升。
然后试图调用底层的BufferedWriter,并传入第一个参数,编译总是出错,于是再次求助DeepSeek,它给出了解释,并提供了正确的写法:
问题分析
类型错误:BufferedWriter 是一个类型,不能直接当值使用
使用结构体初始化语法,必须提供 unbuffered_writer 字段
初始化问题:需要先创建该类型的实例
BufferedWriter(…) 是类型构造器,需要创建该类型的实例才能使用
方法调用:正确的 writer() 调用方式
不需要手动释放资源flush() 确保数据写出
// 创建带缓冲的写入器
var buffered = std.io.BufferedWriter(BUFFER_SIZE, @TypeOf(stdout)){
.unbuffered_writer = stdout,
};
const writer = buffered.writer();
...
// 刷新缓冲区
try buffered.flush();
完整改写后的代码如下:
const std = @import("std");
const ArrayList = std.ArrayList;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const output = std.io.getStdOut().writer();
var stream = std.io.bufferedWriter(output);
const stdout = stream.writer();
// 1. Get filename from command line arguments
var args = std.process.args();
_ = args.next(); // Skip program name
const filename = args.next() orelse {
std.debug.print("Usage: program <filename>\n", .{});
return;
};
// 2. Open and read the file
const file = std.fs.cwd().openFile(filename, .{}) catch |err| {
std.debug.print("Open file '{s}' failed: {}\n", .{ filename, err });
return;
};
defer file.close();
// 3. Read file lines
const content = try file.readToEndAlloc(allocator, std.math.maxInt(usize));
defer allocator.free(content);
var lines = ArrayList([]const u8).init(allocator);
defer lines.deinit();
var iterator = std.mem.splitScalar(u8, content, '\n');
while (iterator.next()) |line| {
try lines.append(line);
}
// 4. Sort
std.mem.sort([]const u8, lines.items, {}, compare);
const BUFFER_SIZE = 64 * 1024; // 64KB 缓冲区
// 创建缓冲写入器 (64KB 缓冲)
//var buffered_writer = std.io.bufferedWriterWithSize(BUFFER_SIZE, stdout);
var buffered_writer = std.io.BufferedWriter(BUFFER_SIZE, @TypeOf(stdout)){
.unbuffered_writer = stdout,
};
const writer = buffered_writer.writer();
// 写入所有行
for (lines.items) |line| {
try writer.print("{s}\n", .{line});
}
// 确保所有缓冲数据被刷新
try buffered_writer.flush();
}
fn compare(context: void, a: []const u8, b: []const u8) bool {
_ = context;
return std.mem.order(u8, a, b) == .lt;
}
编译执行
zig014/zig build-exe main.zig -O ReleaseFast
# 无缓冲的输出
time ./main varchar.txt >vvc.txt
real 0m3.044s
user 0m0.544s
sys 0m0.201s
zig014/zig build-exe mainbuf.zig -O ReleaseFast
#调用默认4096缓冲区大小的bufferedWriter
time ./mainbuf varchar.txt >vvc.txt
real 0m2.929s
user 0m0.483s
sys 0m0.196s
#调用64KB缓冲区大小的BufferedWriter
time ./mainbuf varchar.txt >vvc.txt
real 0m1.168s
user 0m0.459s
sys 0m0.094s
time ./mainbuf varchar.txt >/dev/null
real 0m0.838s
user 0m0.456s
sys 0m0.093s
需要指出输出到文件是否缓冲效率差距几倍的情况我只在WSL中看到,原生的aarch64 Linux差距微乎其微,和输出到/dev/null的差距也很小。
3296

被折叠的 条评论
为什么被折叠?



