Something went wrong. Try again.
A high performance Protein Databank parser written in Zig.
Something went wrong. Try again.
4.6 kB · 124 lines
Zig
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125const strings = @import("strings");const std = @import("std");const fs = std.fs;const sonic = @import("sonic");
const string = []const u8;const char = u8;
const PDB = sonic.PDB;const PDBReader = sonic.PDBReader;const RunRecord = sonic.RunRecord;
test { // this causes 'zig build test' to test any referenced files _ = @import("sonic"); _ = @import("strings");}
const Args = struct { runs: u64 = 100, fileName: string = "", output: string = "times.csv", json: bool = false,
pub fn parseArgs(argsList: []const [:0]const u8) !Args { var args = Args{}; for (argsList, 0..) |arg, idx| { if (strings.equals(arg, "-r")) { args.runs = try std.fmt.parseInt(u64, argsList[idx + 1], 10); } if (strings.equals(arg, "-f")) { args.fileName = @as(string, argsList[idx + 1]); } if (strings.equals(arg, "-o")) { args.output = @as(string, argsList[idx + 1]); } if (strings.equals(arg, "--json")) args.json = true; if (strings.equals(arg, "-h")) { std.debug.print("Usage: exe -r <runs> -f <file> -o <output>\n", .{}); std.process.exit(0); } } if (strings.equals(args.fileName, "")) { std.debug.print("No file specified, please provide a file\n", .{}); std.process.exit(1); } return args; }};
pub fn main(init: std.process.Init) !void { // var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = init.gpa; // defer _ = gpa.deinit(); // const allocator = gpa.allocator(); // const args = try std.process.argsAlloc(allocator); // defer std.process.argsFree(allocator, args); var args_arena = std.heap.ArenaAllocator.init(allocator); defer args_arena.deinit(); const args = try init.minimal.args.toSlice(args_arena.allocator()); const parsedArgs = try Args.parseArgs(args);
var arena = std.heap.ArenaAllocator.init(allocator); defer arena.deinit(); const arenaAllocator = arena.allocator();
const file = try std.Io.Dir.cwd().openFile(init.io, parsedArgs.fileName, .{}); defer file.close(init.io);
if (parsedArgs.runs == 1) { var read_buffer: [4096]u8 = undefined; var file_reader = file.reader(init.io, &read_buffer);
var pdb = try PDB.init(arenaAllocator); defer pdb.deinit(); try pdb.read(&file_reader.interface);
var stdout_buffer: [4096]u8 = undefined; var stdout_writer = std.Io.File.stdout().writerStreaming(init.io, &stdout_buffer); if (parsedArgs.json) { try pdb.writeJson(&stdout_writer.interface); try stdout_writer.interface.writeByte('\n'); try stdout_writer.flush(); } else { try stdout_writer.interface.print("{f}", .{pdb}); try stdout_writer.flush(); } try stdout_writer.interface.flush(); return; }
var timer_start = std.Io.Clock.awake.now(init.io); var times = try std.ArrayList(u64).initCapacity(allocator, @intCast(parsedArgs.runs)); defer times.deinit(allocator); var sum: u64 = 0; const csv = try std.Io.Dir.cwd().createFile(init.io, parsedArgs.output, .{}); defer csv.close(init.io); try RunRecord.writeCSVHeader(init.io, csv);
// var arena = std.heap.ArenaAllocator.init(allocator); // defer arena.deinit(); // const arenaAllocator = arena.allocator();
for (0..parsedArgs.runs) |i| { defer { _ = arena.reset(.retain_capacity); init.io.vtable.fileSeekTo(init.io.userdata, file, 0) catch @panic("file error"); } timer_start = std.Io.Clock.awake.now(init.io); var read_buffer: [4096]u8 = undefined; var file_reader = file.reader(init.io, &read_buffer); var pdb = try PDB.init(arenaAllocator); try pdb.read(&file_reader.interface); const elapsed: u64 = @intCast(timer_start.untilNow(init.io, .awake).toNanoseconds()); try times.append(allocator, elapsed); var runRecord: RunRecord = RunRecord{ .run = i + 1, .time = elapsed, .file = parsedArgs.fileName }; try runRecord.writeCSVLine(init.io, csv); sum += elapsed; std.debug.print("Run {} Complete\n", .{i}); } const average: f32 = @floatFromInt(sum / parsedArgs.runs); const sumF: f32 = @floatFromInt(sum); std.debug.print("sum: {d:.6}s\nparse average: {d:.6} s\n", .{ sumF / 1e+9, average / 1e+9 });}