#!/usr/bin/perl use strict; use warnings; use File::Spec; use File::Path qw(remove_tree); use Cwd qw(getcwd abs_path); my ($files, $depth) = @ARGV; if (!defined $files || !defined $depth) { die "Usage: perl bench.pl \n"; } my $base_dir = getcwd(); my $urn_bin = abs_path(File::Spec->catfile("..", "urn")); my $seed_bin = abs_path("seed.pl"); my $bm_repo = "bm_repo"; my %results; my @actions = qw(Status Add Commit Status(Clean)); sub count_inodes { my $dir = shift; return 0 unless -d $dir; my $count = `find $dir | wc -l`; $count =~ s/\s+//g; return $count; } sub get_size { my $dir = shift; return 0 unless -d $dir; my $size = `du -sk $dir`; $size =~ /^(\d+)/; return $1 || 0; } sub run_benchmark { my ($tool_name) = @_; print "Benchmarking $tool_name...\n"; system("perl $seed_bin $files $depth > /dev/null 2>&1") == 0 or die "Seeding failed"; chdir($bm_repo) or die "Could not enter $bm_repo: $!"; my $meta_dir = ($tool_name eq "URN") ? ".urn" : ".git"; my $init_cmd = ($tool_name eq "URN") ? "perl $urn_bin init" : "git init"; system("$init_cmd > /dev/null 2>&1"); my %cmds = ( "Status" => ($tool_name eq "URN") ? "perl $urn_bin status" : "git status", "Add" => ($tool_name eq "URN") ? "perl $urn_bin add ." : "git add .", "Commit" => ($tool_name eq "URN") ? "perl $urn_bin commit -m 'bench'" : "git commit -m 'bench'", "Status(Clean)" => ($tool_name eq "URN") ? "perl $urn_bin status" : "git status", ); foreach my $action (@actions) { my $cmd = $cmds{$action}; my $raw = `(/usr/bin/time -l $cmd > /dev/null) 2>&1`; my ($real) = $raw =~ /(\d+\.\d+)\s+real/; my ($rss) = $raw =~ /(\d+)\s+maximum resident set size/; my ($maj) = $raw =~ /(\d+)\s+page faults caused by physical I\/O/; my ($min) = $raw =~ /(\d+)\s+page reclaims by virtual memory/; $results{$action}{$tool_name} = { real => $real // "0.00", rss => $rss ? sprintf("%.2f MB", $rss / 1024 / 1024) : "0.00 MB", faults => sprintf("Maj:%d / Min:%d", $maj // 0, $min // 0), inodes => count_inodes($meta_dir), disk => get_size($meta_dir) . " KB", }; } chdir($base_dir) or die $!; remove_tree($bm_repo) if -d $bm_repo; } run_benchmark("URN"); run_benchmark("GIT"); # --- Vertical Report Formatting --- my $out_file = "BM_REPO_SIZE_${files}_${depth}.txt"; open(my $res, '>', $out_file) or die $!; print $res "=============================================================\n"; print $res " BENCHMARK: $files files @ $depth depth\n"; print $res "=============================================================\n\n"; foreach my $action (@actions) { my $u = $results{$action}{"URN"}; my $g = $results{$action}{"GIT"}; print $res "ACTION: $action\n"; print $res "-------------------------------------------------------------\n"; printf $res "%-15s | %-20s | %-20s\n", "METRIC", "URN", "GIT"; print $res "----------------+----------------------+---------------------\n"; printf $res "%-15s | %20s | %20s\n", "Time", $u->{real}."s", $g->{real}."s"; printf $res "%-15s | %20s | %20s\n", "Max RSS", $u->{rss}, $g->{rss}; printf $res "%-15s | %20s | %20s\n", "Page faults", $u->{faults}, $g->{faults}; printf $res "%-15s | %20s | %20s\n", "Inodes", $u->{inodes}, $g->{inodes}; printf $res "%-15s | %20s | %20s\n", "Repo size", $u->{disk}, $g->{disk}; print $res "-------------------------------------------------------------\n\n"; } close($res); print "\nComparison complete! Results saved to $out_file\n"; my $pager = $ENV{PAGER} || 'less'; system("$pager $out_file");