Skip to content

Commit cc4f0ee

Browse files
authored
docs(benchmarks): add benchmarks to readme (#52)
* docs(benchmarks): add benchmarks to readme * tables * minor change in table title * fix(docs): update hardware specifications in README * updated tests * cache * nitpick * move benchmark methodology section * update toc * charts
1 parent 964c41c commit cc4f0ee

7 files changed

+274
-4
lines changed

Diff for: .gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ coverage.txt
77
coverage.html
88
test.sh
99
.idea
10-
*.png
1110
*.pprof
1211
test_ant/*
1312
.pgo_profiles/

Diff for: README.md

+155-3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ mkbrr create path/to/file -t https://example-tracker.com/announce -e
8282
- [Tracker-Specific Features](#tracker-specific-features)
8383
- [Incomplete Season Pack Detection](#incomplete-season-pack-detection)
8484
- [Performance](#performance)
85+
- [Benchmark Methodology](#benchmark-methodology)
86+
- [Benchmark Results](#benchmark-results)
87+
- [Speed Comparison](#speed-comparison)
88+
- [Consistency](#consistency)
89+
- [Hardware Specifications](#hardware-specifications)
8590
- [License](#license)
8691

8792
## Installation
@@ -283,11 +288,158 @@ Wrote title.torrent (elapsed 3.22s)
283288

284289
## Performance
285290

286-
mkbrr is optimized for speed, and outperforms other popular tools.
287-
We will post some benchmarks later on.
291+
mkbrr is optimized for speed and consistently outperforms other popular torrent creation tools in our benchmarks.
292+
293+
### Benchmark Methodology
294+
295+
All tests were performed using [hyperfine](https://github.com/sharkdp/hyperfine) with 5 runs per tool after a warm-up run. Cache was cleared between runs on the servers, but not on the Macbook.
296+
297+
### Benchmark Results
298+
299+
| Hardware | Test Size | mkbrr | mktorrent | torrenttools | torf |
300+
|----------|---------------|-------|-----------|--------------|------|
301+
| **Leaseweb Server (SSD)** | 21 GiB | **7.24s** | 45.41s | 9.07s | 8.85s |
302+
| **Hetzner Server (HDD)** | 14 GiB | **41.02s** | 68.17s | 47.97s | 58.19s |
303+
| **Macbook Pro M4 (NVME)** | 30 GiB | **9.71s** | 10.90s | - | 9.78s |
304+
305+
![Benchmark Comparison](docs/benchmarks/benchmark_comparison.png)
306+
307+
### Speed Comparison
308+
309+
| Hardware | vs mktorrent | vs torrenttools | vs torf |
310+
|----------|-------------|----------------|---------|
311+
| **Leaseweb Server (SSD)** | 6.3× faster | 1.3× faster | 1.2× faster |
312+
| **Hetzner Server (HDD)** | 1.7× faster | 1.2× faster | 1.4× faster |
313+
| **Macbook Pro M4 (NVME)** | 1.1× faster | - | Similar |
314+
315+
![Speed Comparison](docs/benchmarks/speed_comparison.png)
316+
317+
### Consistency
318+
319+
Besides raw speed, mkbrr shows more consistent performance between runs, with standard deviation percentages between 0.25-3.7% across platforms compared to much higher variances for other tools (up to 39%). This predictable performance is particularly noticeable on mechanical storage where other tools showed wider fluctuations.
320+
321+
![Consistency Comparison](docs/benchmarks/consistency_comparison.png)
322+
323+
### Hardware Specifications
324+
325+
#### Leaseweb Dedicated Server (SSD)
326+
- CPU: Intel Xeon E-2274G @ 4.00GHz
327+
- RAM: 32GB
328+
- Storage: 1 × SAMSUNG MZQL21T9HCJR-00A07 1.92TB SSD
329+
330+
#### Hetzner Dedicated Server (HDD)
331+
- CPU: AMD Ryzen 5 3600 (12) @ 4.71GHz
332+
- RAM: 64GB
333+
- Storage: 4 × TOSHIBA MG08ACA16TEY in RAID0
334+
335+
#### Macbook Pro M4
336+
- CPU: Apple M4
337+
- RAM: 16GB
338+
- Storage: 512GB NVME
339+
340+
### Full results
341+
342+
<details>
343+
<summary>View Full Benchmark Commands & Results</summary>
344+
345+
#### Leaseweb Server (21 GiB 1080p season pack)
346+
347+
```bash
348+
hyperfine --warmup 1 --runs 5 \
349+
--setup 'sudo sync && sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"' \
350+
--prepare 'sudo sync && sudo sh -c "echo 3 > /proc/sys/vm/drop_caches" && rm -f /home/user/Show.S01.DL.1080p.WEB.H264-GROUP.torrent' \
351+
'mkbrr create /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP' \
352+
'mktorrent /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP' \
353+
'torrenttools create --threads 8 ~/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP' \
354+
'torf --threads 8 /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP'
355+
356+
Benchmark 1: mkbrr create /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP
357+
Time (mean ± σ): 7.244 s ± 0.018 s [User: 31.245 s, System: 7.554 s]
358+
Range (min … max): 7.225 s … 7.270 s 5 runs
359+
360+
Benchmark 2: mktorrent /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP
361+
Time (mean ± σ): 45.407 s ± 0.163 s [User: 36.495 s, System: 4.983 s]
362+
Range (min … max): 45.135 s … 45.539 s 5 runs
363+
364+
Benchmark 3: torrenttools create --threads 8 ~/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP
365+
Time (mean ± σ): 9.074 s ± 0.093 s [User: 29.248 s, System: 5.228 s]
366+
Range (min … max): 8.908 s … 9.122 s 5 runs
367+
368+
Benchmark 4: torf --threads 8 /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP
369+
Time (mean ± σ): 8.854 s ± 0.077 s [User: 25.829 s, System: 5.136 s]
370+
Range (min … max): 8.771 s … 8.937 s 5 runs
371+
372+
Summary
373+
'mkbrr create /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP' ran
374+
1.22 ± 0.01 times faster than 'torf --threads 8 /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP'
375+
1.25 ± 0.01 times faster than 'torrenttools create --threads 8 ~/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP'
376+
6.27 ± 0.03 times faster than 'mktorrent /home/user/torrents/qbittorrent/Show.S01.DL.1080p.WEB.H264-GROUP'
377+
```
378+
379+
#### Hetzner Server (14 GiB 1080p season pack)
380+
381+
```bash
382+
hyperfine --warmup 1 --runs 5 \
383+
--setup 'sudo sync && sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"' \
384+
--prepare 'sudo sync && sudo sh -c "echo 3 > /proc/sys/vm/drop_caches" && rm -f /home/user/mkbrr/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP.torrent' \
385+
'mkbrr create ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP' \
386+
'mktorrent ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP' \
387+
'torrenttools create --threads 12 ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP' \
388+
'torf --threads 12 ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP'
389+
390+
Benchmark 1: mkbrr create ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
391+
Time (mean ± σ): 41.022 s ± 0.979 s [User: 13.691 s, System: 6.747 s]
392+
Range (min … max): 39.938 s … 42.467 s 5 runs
393+
394+
Benchmark 2: mktorrent ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
395+
Time (mean ± σ): 68.168 s ± 26.654 s [User: 17.934 s, System: 6.543 s]
396+
Range (min … max): 39.268 s … 97.574 s 5 runs
397+
398+
Benchmark 3: torrenttools create --threads 12 ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
399+
Time (mean ± σ): 47.968 s ± 10.552 s [User: 7.052 s, System: 6.551 s]
400+
Range (min … max): 39.460 s … 66.296 s 5 runs
401+
402+
Benchmark 4: torf --threads 12 ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
403+
Time (mean ± σ): 58.187 s ± 5.787 s [User: 7.185 s, System: 6.511 s]
404+
Range (min … max): 50.125 s … 65.807 s 5 runs
405+
406+
Summary
407+
mkbrr create ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP ran
408+
1.17 ± 0.26 times faster than torrenttools create --threads 12 ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
409+
1.42 ± 0.15 times faster than torf --threads 12 ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
410+
1.66 ± 0.65 times faster than mktorrent ~/torrents/qbittorrent/tv/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
411+
```
412+
413+
#### Macbook Pro M4 (30 GiB 1080p season pack)
414+
415+
```bash
416+
hyperfine --warmup 1 --runs 5 \
417+
--prepare 'rm -f Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP.torrent' \
418+
'mkbrr create ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP' \
419+
'mktorrent ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP' \
420+
'torf --threads 10 ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP'
421+
422+
Benchmark 1: mkbrr create ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
423+
Time (mean ± σ): 9.708 s ± 0.355 s [User: 10.823 s, System: 4.297 s]
424+
Range (min … max): 9.479 s … 10.323 s 5 runs
425+
426+
Benchmark 2: mktorrent ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
427+
Time (mean ± σ): 10.897 s ± 0.701 s [User: 11.021 s, System: 3.038 s]
428+
Range (min … max): 9.950 s … 11.620 s 5 runs
429+
430+
Benchmark 3: torf --threads 10 ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
431+
Time (mean ± σ): 9.779 s ± 0.749 s [User: 10.776 s, System: 5.253 s]
432+
Range (min … max): 9.383 s … 11.112 s 5 runs
433+
434+
Summary
435+
mkbrr create ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP ran
436+
1.01 ± 0.09 times faster than torf --threads 10 ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
437+
1.12 ± 0.08 times faster than mktorrent ~/Desktop/Show.S01.1080p.SRC.WEB-DL.DDP5.1.H.264-GRP
438+
```
439+
</details>
288440

289441
## License
290442

291443
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
292444

293-
See [LICENSE](LICENSE) for the full license text.
445+
See [LICENSE](LICENSE) for the full license text.

Diff for: docs/benchmarks/benchmark_comparison.png

106 KB
Loading

Diff for: docs/benchmarks/benchmark_plots.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
import pandas as pd
4+
import seaborn as sns
5+
6+
# Set style
7+
plt.style.use('bmh')
8+
sns.set_theme(style="whitegrid")
9+
10+
# Data
11+
hardware = ['Leaseweb (SSD)', 'Hetzner (HDD)', 'Macbook (NVME)']
12+
test_size = [21, 14, 30] # GiB
13+
14+
# Times in seconds
15+
mkbrr = [7.24, 41.02, 9.71]
16+
mktorrent = [45.41, 68.17, 10.90]
17+
torrenttools = [9.07, 47.97, np.nan]
18+
torf = [8.85, 58.19, 9.78]
19+
20+
# Create DataFrame
21+
df = pd.DataFrame({
22+
'Hardware': hardware,
23+
'Test Size (GiB)': test_size,
24+
'mkbrr': mkbrr,
25+
'mktorrent': mktorrent,
26+
'torrenttools': torrenttools,
27+
'torf': torf
28+
})
29+
30+
plt.rcParams['figure.figsize'] = (10, 6)
31+
plt.rcParams['font.size'] = 10
32+
33+
# Create horizontal bar plot
34+
fig, ax = plt.subplots()
35+
y = np.arange(len(hardware))
36+
width = 0.2
37+
38+
ax.barh(y - width*1.5, mkbrr, width, label='mkbrr', color='#2ecc71')
39+
ax.barh(y - width/2, mktorrent, width, label='mktorrent', color='#e74c3c')
40+
ax.barh(y + width/2, torrenttools, width, label='torrenttools', color='#3498db')
41+
ax.barh(y + width*1.5, torf, width, label='torf', color='#f1c40f')
42+
43+
# Customize plot
44+
ax.set_xlabel('Time (seconds)')
45+
ax.set_title('Torrent Creation Performance Comparison')
46+
ax.set_yticks(y)
47+
ax.set_yticklabels(hardware)
48+
ax.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
49+
50+
# Add test size labels
51+
for i, size in enumerate(test_size):
52+
ax.text(1, i, f'{size} GiB', ha='left', va='center')
53+
54+
# Adjust layout
55+
plt.tight_layout()
56+
57+
# Save plot
58+
plt.savefig('benchmark_comparison.png', dpi=300, bbox_inches='tight')
59+
60+
# Create speed comparison plot
61+
speed_vs_mktorrent = [6.3, 1.7, 1.1]
62+
speed_vs_torrenttools = [1.3, 1.2, np.nan]
63+
speed_vs_torf = [1.2, 1.4, 1.0]
64+
65+
fig, ax = plt.subplots()
66+
y = np.arange(len(hardware))
67+
width = 0.25
68+
69+
ax.barh(y - width, speed_vs_mktorrent, width, label='vs mktorrent', color='#e74c3c')
70+
ax.barh(y, speed_vs_torrenttools, width, label='vs torrenttools', color='#3498db')
71+
ax.barh(y + width, speed_vs_torf, width, label='vs torf', color='#f1c40f')
72+
73+
# Customize plot
74+
ax.set_xlabel('Speed Multiplier (×)')
75+
ax.set_title('mkbrr Speed Comparison')
76+
ax.set_yticks(y)
77+
ax.set_yticklabels(hardware)
78+
ax.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
79+
80+
# Add vertical line at 1.0
81+
ax.axvline(x=1.0, color='black', linestyle='--', alpha=0.3)
82+
83+
# Adjust layout
84+
plt.tight_layout()
85+
86+
# Save plot
87+
plt.savefig('speed_comparison.png', dpi=300, bbox_inches='tight')
88+
89+
# Create consistency plot (standard deviation percentages)
90+
std_mkbrr = [0.25, 2.39, 3.66]
91+
std_mktorrent = [0.36, 39.10, 6.43]
92+
std_torrenttools = [1.02, 22.00, np.nan]
93+
std_torf = [0.87, 9.95, 7.66]
94+
95+
fig, ax = plt.subplots()
96+
y = np.arange(len(hardware))
97+
width = 0.2
98+
99+
ax.barh(y - width*1.5, std_mkbrr, width, label='mkbrr', color='#2ecc71')
100+
ax.barh(y - width/2, std_mktorrent, width, label='mktorrent', color='#e74c3c')
101+
ax.barh(y + width/2, std_torrenttools, width, label='torrenttools', color='#3498db')
102+
ax.barh(y + width*1.5, std_torf, width, label='torf', color='#f1c40f')
103+
104+
# Customize plot
105+
ax.set_xlabel('Standard Deviation (%)')
106+
ax.set_title('Performance Consistency Comparison')
107+
ax.set_yticks(y)
108+
ax.set_yticklabels(hardware)
109+
ax.legend(bbox_to_anchor=(1.02, 1), loc='upper left')
110+
111+
# Adjust layout
112+
plt.tight_layout()
113+
114+
# Save plot
115+
plt.savefig('consistency_comparison.png', dpi=300, bbox_inches='tight')

Diff for: docs/benchmarks/consistency_comparison.png

101 KB
Loading

Diff for: docs/benchmarks/requirements.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
matplotlib>=3.7.0
2+
numpy>=1.24.0
3+
pandas>=2.0.0
4+
seaborn>=0.12.0

Diff for: docs/benchmarks/speed_comparison.png

97 KB
Loading

0 commit comments

Comments
 (0)