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:
@@ -42,6 +42,49 @@ arctan(x) = x - x³/3 + x⁵/5 - x⁷/7 + ...
|
|||||||
|
|
||||||
## Resultat
|
## Resultat
|
||||||
|
|
||||||
|
### Binärstorlekar
|
||||||
|
|
||||||
|
Filstorlekar för kompilerade binärer (där tillämpligt):
|
||||||
|
|
||||||
|
| Språk | Binärstorlek | Typ |
|
||||||
|
|-------|--------------|-----|
|
||||||
|
| C | 34K | Native binary |
|
||||||
|
| Assembly | 49K | Native binary |
|
||||||
|
| Fortran | 34K | Native binary |
|
||||||
|
| Objective-C | 50K | Native binary |
|
||||||
|
| Swift | 76K | Native binary |
|
||||||
|
| Nim | 149K | Native binary |
|
||||||
|
| Rust | 497K | Native binary |
|
||||||
|
| Odin | 422K | Native binary |
|
||||||
|
| C++ | 221K | Native binary |
|
||||||
|
| Zig | 2.0M | Native binary |
|
||||||
|
| Crystal | 1.5M | Native binary |
|
||||||
|
| D | 1.3M | Native binary |
|
||||||
|
| Go | 2.5M | Native binary |
|
||||||
|
| Dart | 5.4M | Native binary |
|
||||||
|
| Haskell | 13M | Native binary |
|
||||||
|
| C# | 122K | .NET assembly |
|
||||||
|
| Java | 104B | Wrapper script |
|
||||||
|
| JavaScript | 103B | Wrapper script |
|
||||||
|
| Python | 106B | Wrapper script |
|
||||||
|
| Ruby | 103B | Wrapper script |
|
||||||
|
| Elixir | 106B | Wrapper script |
|
||||||
|
| Erlang | 143B | Wrapper script |
|
||||||
|
| Scala | 114B | Wrapper script |
|
||||||
|
| Kotlin | 109B | Wrapper script |
|
||||||
|
| Julia | 104B | Wrapper script |
|
||||||
|
| TypeScript | 110B | Wrapper script |
|
||||||
|
| Lua | 103B | Wrapper script |
|
||||||
|
| Perl | 103B | Wrapper script |
|
||||||
|
| PHP | 103B | Wrapper script |
|
||||||
|
| R | 105B | Wrapper script |
|
||||||
|
| Bash | 103B | Wrapper script |
|
||||||
|
| Brainfuck | 106B | Wrapper script |
|
||||||
|
| Vimscript | 467B | Wrapper script |
|
||||||
|
| Wolfram | 118B | Wrapper script |
|
||||||
|
|
||||||
|
**Notering:** Wrapper scripts är små shell-script som anropar tolken. Kompilerade språk har faktiska binärer med inbyggd kod.
|
||||||
|
|
||||||
### 100 decimaler
|
### 100 decimaler
|
||||||
|
|
||||||
| Språk | Tid (ms) | Kategori | Status |
|
| Språk | Tid (ms) | Kategori | Status |
|
||||||
@@ -271,6 +314,7 @@ Bash: 4456 ms (Shell interpreter, process spawning)
|
|||||||
- 100 decimaler: 6 ms
|
- 100 decimaler: 6 ms
|
||||||
- 1000 decimaler: 4 ms
|
- 1000 decimaler: 4 ms
|
||||||
- 10000 decimaler: 24 ms
|
- 10000 decimaler: 24 ms
|
||||||
|
- **Binärstorlek:** 34K
|
||||||
|
|
||||||
**Teknisk analys:**
|
**Teknisk analys:**
|
||||||
- Kompilerar direkt till ARM64-maskinkod
|
- Kompilerar direkt till ARM64-maskinkod
|
||||||
@@ -288,6 +332,7 @@ Bash: 4456 ms (Shell interpreter, process spawning)
|
|||||||
- 100 decimaler: 7 ms
|
- 100 decimaler: 7 ms
|
||||||
- 1000 decimaler: 4 ms
|
- 1000 decimaler: 4 ms
|
||||||
- 10000 decimaler: 27 ms
|
- 10000 decimaler: 27 ms
|
||||||
|
- **Binärstorlek:** 49K
|
||||||
|
|
||||||
**Teknisk analys:**
|
**Teknisk analys:**
|
||||||
- Direkt ARM64-instruktioner
|
- Direkt ARM64-instruktioner
|
||||||
@@ -305,6 +350,7 @@ Bash: 4456 ms (Shell interpreter, process spawning)
|
|||||||
- 100 decimaler: 7 ms
|
- 100 decimaler: 7 ms
|
||||||
- 1000 decimaler: 5 ms
|
- 1000 decimaler: 5 ms
|
||||||
- 10000 decimaler: 53 ms
|
- 10000 decimaler: 53 ms
|
||||||
|
- **Binärstorlek:** 497K
|
||||||
|
|
||||||
**Teknisk analys:**
|
**Teknisk analys:**
|
||||||
- Kompilerar till native code via LLVM
|
- Kompilerar till native code via LLVM
|
||||||
@@ -322,6 +368,7 @@ Bash: 4456 ms (Shell interpreter, process spawning)
|
|||||||
- 100 decimaler: 34 ms
|
- 100 decimaler: 34 ms
|
||||||
- 1000 decimaler: 38 ms
|
- 1000 decimaler: 38 ms
|
||||||
- 10000 decimaler: 300 ms
|
- 10000 decimaler: 300 ms
|
||||||
|
- **Binärstorlek:** 106B (wrapper script)
|
||||||
|
|
||||||
**Teknisk analys:**
|
**Teknisk analys:**
|
||||||
- CPython-tolk exekverar bytecode
|
- CPython-tolk exekverar bytecode
|
||||||
@@ -339,6 +386,7 @@ Bash: 4456 ms (Shell interpreter, process spawning)
|
|||||||
- 100 decimaler: 77 ms
|
- 100 decimaler: 77 ms
|
||||||
- 1000 decimaler: 195 ms
|
- 1000 decimaler: 195 ms
|
||||||
- 10000 decimaler: 10065 ms
|
- 10000 decimaler: 10065 ms
|
||||||
|
- **Binärstorlek:** 103B (wrapper script)
|
||||||
|
|
||||||
**Teknisk analys:**
|
**Teknisk analys:**
|
||||||
- V8-motorn JIT-kompilerar JavaScript
|
- V8-motorn JIT-kompilerar JavaScript
|
||||||
|
|||||||
+95
-17
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/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
|
# Run each program 3 times and take the average
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
@@ -20,6 +20,8 @@ DECIMALS=$1
|
|||||||
# Colors for output
|
# Colors for output
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
# Function to verify result against facit
|
# Function to verify result against facit
|
||||||
@@ -35,6 +37,37 @@ verify() {
|
|||||||
fi
|
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 "=== Pi-beräkning med $DECIMALS decimaler (4 körningar, genomsnitt av 3 efter warmup) ==="
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -49,42 +82,78 @@ run_program() {
|
|||||||
printf "%-12s " "$name"
|
printf "%-12s " "$name"
|
||||||
|
|
||||||
local total_time=0
|
local total_time=0
|
||||||
|
local total_memory=0
|
||||||
local success_count=0
|
local success_count=0
|
||||||
local result
|
local result
|
||||||
|
local peak_memory=0
|
||||||
|
|
||||||
# Run 4 times, discard first run (warmup)
|
# Run 4 times, discard first run (warmup)
|
||||||
for i in 1 2 3 4; do
|
for i in 1 2 3 4; do
|
||||||
|
local mem_profile_file="/tmp/${name}_mem_$$_$i"
|
||||||
local start=$(date +%s%N)
|
local start=$(date +%s%N)
|
||||||
|
|
||||||
if result=$("$@" 2>/dev/null); then
|
# Run program and capture PID for memory profiling
|
||||||
local end=$(date +%s%N)
|
if [ "$i" -gt 1 ]; then
|
||||||
local elapsed=$(( (end - start) / 1000000 ))
|
# For runs 2-4, profile memory
|
||||||
|
"$@" 2>/dev/null &
|
||||||
|
local pid=$!
|
||||||
|
|
||||||
|
# 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 ))
|
||||||
|
|
||||||
# Skip first run (warmup)
|
|
||||||
if [ $i -gt 1 ]; then
|
|
||||||
total_time=$((total_time + elapsed))
|
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
|
if verify "$result" "$DECIMALS"; then
|
||||||
((success_count++))
|
((success_count++))
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}ERROR${NC}"
|
||||||
|
results+=("999999 $name ERROR")
|
||||||
|
rm -f "$mem_profile_file"
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
rm -f "$mem_profile_file"
|
||||||
else
|
else
|
||||||
# If any run fails, mark as error
|
# First run (warmup) - just execute without profiling
|
||||||
echo -e "${RED}ERROR${NC}"
|
if result=$("$@" 2>/dev/null); then
|
||||||
results+=("999999 $name ERROR")
|
:
|
||||||
return
|
else
|
||||||
|
echo -e "${RED}ERROR${NC}"
|
||||||
|
results+=("999999 $name ERROR")
|
||||||
|
return
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Calculate average
|
# Calculate averages
|
||||||
local avg_time=$((total_time / 3))
|
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
|
if [ $success_count -eq 3 ]; then
|
||||||
echo -e "${GREEN}SUCCESS${NC} $avg_time ms (avg)"
|
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")
|
results+=("$avg_time $name SUCCESS $avg_memory $peak_memory")
|
||||||
else
|
else
|
||||||
echo -e "${RED}FAILED${NC} $avg_time ms (avg)"
|
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")
|
results+=("$avg_time $name FAILED $avg_memory $peak_memory")
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,17 +201,26 @@ echo ""
|
|||||||
IFS=$'\n' sorted=($(printf '%s\n' "${results[@]}" | sort -n))
|
IFS=$'\n' sorted=($(printf '%s\n' "${results[@]}" | sort -n))
|
||||||
unset IFS
|
unset IFS
|
||||||
|
|
||||||
|
echo "Språk Status Tid (ms) Minne (MB)"
|
||||||
|
echo "================================================"
|
||||||
|
|
||||||
for entry in "${sorted[@]}"; do
|
for entry in "${sorted[@]}"; do
|
||||||
time_ms=$(echo "$entry" | awk '{print $1}')
|
time_ms=$(echo "$entry" | awk '{print $1}')
|
||||||
name=$(echo "$entry" | awk '{print $2}')
|
name=$(echo "$entry" | awk '{print $2}')
|
||||||
status=$(echo "$entry" | awk '{print $3}')
|
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"
|
printf "%-12s " "$name"
|
||||||
|
|
||||||
if [ "$status" = "SUCCESS" ]; then
|
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
|
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
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user