Explore differences in language design, syntax, and developer experience.
https://github.com/Monty/ConvertEpisodeSequences.git
This repository contains programs with identical functionality written in Python, Rust, Go, and Swift.
It began as a simple Python script that compresses sequential TV episode listings. I later reimplemented it in Rust and Go to compare how each language handles common programming tasks such as regular expressions, string manipulation, state management across iterations, error handling, command-line argument parsing, file I/O, and formatted output to stdout and stderr.
My goal was to explore differences in language design, syntax, and developer experience when implementing the same logic.
The repository also includes:
# From a file
./compress_newEpisodes.py newEpisodes-01.txt
./compress_newEpisodes.py newEpisodes-02.txt > newEpisodes-02-out
# From stdin
./newEpisodes.sh | ./compress_newEpisodes.py > newEpisodes.txt
# Help
./compress_newEpisodes.py --help
Each week I run a newEpisodes.sh script that lists new episodes
of TV shows on the streaming services I subscribe to. Itβs much
easier to check a consolidated list than to scroll through multiple
websites to see whatβs newly available.
These listings often include numerically sequential episodes of the same series interspersed with non-sequential ones, for example:
Cassandre, S03E04, The Grey Wolf
Catch and Release, S01E02, Episode 02
Catch and Release, S01E03, Episode 03
Catch and Release, S01E04, Episode 04
Public Enemy, S03E05, Excommunication
Public Enemy, S03E06, The Beast
The Bench, S01E01, Episode 1
The Bench, S01E02, Episode 2
The Bench, S01E03, Episode 3
The Bench, S01E04, Episode 4
Twenty Twelve, S02E001, Boycott - Part 1
Twenty Twelve, S02E002, Boycott - Part 2
Which can be reduced by about 50% to:
Cassandre, S03E04, The Grey Wolf
Catch and Release, S01E02-04, Episode 02-04
Public Enemy, S03E05, Excommunication
Public Enemy, S03E06, The Beast
The Bench, S01E01-04, Episode 1-4
Twenty Twelve, S02E001-002, Boycott - Part 1-2
Doing this manually each week became tedious. While tools like
sed or awk could automate parts of it, a small Python script
was more effective end maintainable. After validating its correctness,
I reimplemented the same logic in Rust and Go as a learning exercise.
Rust, Go and compiled Swift are faster, but Python still wins for convenience β it handles a 233 KB, 5,944-line file in under 45 ms, and thereβs no compilation step to worry about.
# Run benchmarks
$ hyperfine --warmup 10 \
'./compress_newEpisodes_rust squishTest.txt >/dev/null' \
'./compress_newEpisodes_go squishTest.txt >/dev/null' \
'./compress_newEpisodes_swift squishTest.txt >/dev/null' \
'./compress_newEpisodes.py squishTest.txt >/dev/null' \
'./compress_newEpisodes.swift squishTest.txt >/dev/null'
Benchmark 1: ./compress_newEpisodes_rust squishTest.txt >/dev/null
Time (mean Β± Ο): 10.0 ms Β± 0.3 ms [User: 8.2 ms, System: 1.6 ms]
Range (min β¦ max): 9.6 ms β¦ 11.0 ms 233 runs
Benchmark 2: ./compress_newEpisodes_go squishTest.txt >/dev/null
Time (mean Β± Ο): 14.1 ms Β± 0.2 ms [User: 12.1 ms, System: 2.1ms]
Range (min β¦ max): 13.6 ms β¦ 14.9 ms 181 runs
Benchmark 3: ./compress_newEpisodes_swift squishTest.txt >/dev/null
Time (mean Β± Ο): 38.3 ms Β± 0.5 ms [User: 36.4 ms, System: 1.5ms]
Range (min β¦ max): 37.4 ms β¦ 40.6 ms 73 runs
Benchmark 4: ./compress_newEpisodes.py squishTest.txt >/dev/null
Time (mean Β± Ο): 44.0 ms Β± 0.4 ms [User: 34.7 ms, System: 6.9ms]
Range (min β¦ max): 42.7 ms β¦ 44.6 ms 63 runs
Benchmark 5: ./compress_newEpisodes.swift squishTest.txt >/dev/null
Time (mean Β± Ο): 364.4 ms Β± 1.0 ms [User: 311.3 ms, System: 34.6 ms]
Range (min β¦ max): 362.3 ms β¦ 365.5 ms 10 runs
Summary
./compress_newEpisodes_rust squishTest.txt >/dev/null ran
1.41 Β± 0.05 times faster than ./compress_newEpisodes_go squishTest.txt >/dev/null
3.83 Β± 0.13 times faster than ./compress_newEpisodes_swift squishTest.txt >/dev/null
4.40 Β± 0.14 times faster than ./compress_newEpisodes.py squishTest.txt >/dev/null
36.43 Β± 1.10 times faster than ./compress_newEpisodes.swift squishTest.txt >/dev/null