Add binary sizes and memory profiling

- Added binary size section to README with actual file sizes
- Updated run_all.sh to profile memory usage during execution
- Memory profiling shows average and peak memory consumption
- All data from actual measurements on Apple A18 Pro
- Binary sizes range from 103B (wrapper scripts) to 13M (Haskell)
This commit is contained in:
Ein Anderssono
2026-04-23 00:47:33 +02:00
parent 3912ac9e6e
commit 379ee1da35
2 changed files with 143 additions and 17 deletions
+95 -17
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Run all pi calculation programs and measure performance
# Run all pi calculation programs and measure performance and memory
# Run each program 3 times and take the average
set -e
@@ -20,6 +20,8 @@ DECIMALS=$1
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to verify result against facit
@@ -35,6 +37,37 @@ verify() {
fi
}
# Function to get memory usage of a process (in KB)
get_memory_usage() {
local pid=$1
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
# Use ps to get RSS (resident set size) in KB
ps -o rss= -p "$pid" 2>/dev/null || echo "0"
else
echo "0"
fi
}
# Function to profile memory during execution
profile_memory() {
local pid=$1
local output_file=$2
local peak_mem=0
local current_mem
# Sample memory every 10ms while process is running
while kill -0 "$pid" 2>/dev/null; do
current_mem=$(get_memory_usage "$pid")
if [ "$current_mem" -gt "$peak_mem" ]; then
peak_mem=$current_mem
fi
echo "$current_mem" >> "$output_file"
sleep 0.01 2>/dev/null || sleep 0.1
done
echo "$peak_mem"
}
echo "=== Pi-beräkning med $DECIMALS decimaler (4 körningar, genomsnitt av 3 efter warmup) ==="
echo ""
@@ -49,42 +82,78 @@ run_program() {
printf "%-12s " "$name"
local total_time=0
local total_memory=0
local success_count=0
local result
local peak_memory=0
# Run 4 times, discard first run (warmup)
for i in 1 2 3 4; do
local mem_profile_file="/tmp/${name}_mem_$$_$i"
local start=$(date +%s%N)
if result=$("$@" 2>/dev/null); then
local end=$(date +%s%N)
local elapsed=$(( (end - start) / 1000000 ))
# Run program and capture PID for memory profiling
if [ "$i" -gt 1 ]; then
# For runs 2-4, profile memory
"$@" 2>/dev/null &
local pid=$!
# Skip first run (warmup)
if [ $i -gt 1 ]; then
# Profile memory in background
local peak_mem=$(profile_memory "$pid" "$mem_profile_file")
# Wait for process to complete
wait "$pid" 2>/dev/null
local exit_code=$?
if [ $exit_code -eq 0 ]; then
result=$("$@" 2>/dev/null)
local end=$(date +%s%N)
local elapsed=$(( (end - start) / 1000000 ))
total_time=$((total_time + elapsed))
total_memory=$((total_memory + peak_mem))
if [ "$peak_mem" -gt "$peak_memory" ]; then
peak_memory=$peak_mem
fi
if verify "$result" "$DECIMALS"; then
((success_count++))
fi
else
echo -e "${RED}ERROR${NC}"
results+=("999999 $name ERROR")
rm -f "$mem_profile_file"
return
fi
rm -f "$mem_profile_file"
else
# If any run fails, mark as error
echo -e "${RED}ERROR${NC}"
results+=("999999 $name ERROR")
return
# First run (warmup) - just execute without profiling
if result=$("$@" 2>/dev/null); then
:
else
echo -e "${RED}ERROR${NC}"
results+=("999999 $name ERROR")
return
fi
fi
done
# Calculate average
# Calculate averages
local avg_time=$((total_time / 3))
local avg_memory=$((total_memory / 3))
# Convert memory to MB for display
local avg_memory_mb=$((avg_memory / 1024))
local peak_memory_mb=$((peak_memory / 1024))
if [ $success_count -eq 3 ]; then
echo -e "${GREEN}SUCCESS${NC} $avg_time ms (avg)"
results+=("$avg_time $name SUCCESS")
echo -e "${GREEN}SUCCESS${NC} $avg_time ms (avg), ${BLUE}${avg_memory_mb}MB avg, ${YELLOW}${peak_memory_mb}MB peak${NC}"
results+=("$avg_time $name SUCCESS $avg_memory $peak_memory")
else
echo -e "${RED}FAILED${NC} $avg_time ms (avg)"
results+=("$avg_time $name FAILED")
echo -e "${RED}FAILED${NC} $avg_time ms (avg), ${BLUE}${avg_memory_mb}MB avg, ${YELLOW}${peak_memory_mb}MB peak${NC}"
results+=("$avg_time $name FAILED $avg_memory $peak_memory")
fi
}
@@ -132,17 +201,26 @@ echo ""
IFS=$'\n' sorted=($(printf '%s\n' "${results[@]}" | sort -n))
unset IFS
echo "Språk Status Tid (ms) Minne (MB)"
echo "================================================"
for entry in "${sorted[@]}"; do
time_ms=$(echo "$entry" | awk '{print $1}')
name=$(echo "$entry" | awk '{print $2}')
status=$(echo "$entry" | awk '{print $3}')
avg_mem=$(echo "$entry" | awk '{print $4}')
peak_mem=$(echo "$entry" | awk '{print $5}')
# Convert to MB
avg_mem_mb=$((avg_mem / 1024))
peak_mem_mb=$((peak_mem / 1024))
printf "%-12s " "$name"
if [ "$status" = "SUCCESS" ]; then
echo -e "${GREEN}$status${NC} $time_ms ms"
echo -e "${GREEN}$status${NC} $time_ms ms ${BLUE}${avg_mem_mb}MB avg / ${YELLOW}${peak_mem_mb}MB peak${NC}"
else
echo -e "${RED}$status${NC} $time_ms ms"
echo -e "${RED}$status${NC} $time_ms ms ${BLUE}${avg_mem_mb}MB avg / ${YELLOW}${peak_mem_mb}MB peak${NC}"
fi
done