Last active
August 15, 2024 17:18
-
-
Save llimllib/a98f5c185e096f6f6ec16c8172054930 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./test.sh | |
node version: v22.4.0 | |
python version: Python 3.12.2 | |
go version: go version go1.22.6 darwin/arm64 | |
rg version: ripgrep 14.1.0 | |
features:-simd-accel,+pcre2 | |
simd(compile):+NEON | |
simd(runtime):+NEON | |
PCRE2 10.42 is available (JIT is available) | |
Benchmark 1: node /tmp/test.js | |
Time (mean ± σ): 401.8 ms ± 4.6 ms [User: 393.6 ms, System: 4.6 ms] | |
Range (min … max): 396.5 ms … 411.7 ms 10 runs | |
Benchmark 2: python /tmp/test.py | |
Time (mean ± σ): 317.9 ms ± 0.8 ms [User: 311.4 ms, System: 3.8 ms] | |
Range (min … max): 317.0 ms … 318.9 ms 10 runs | |
Benchmark 3: /tmp/gotest | |
Time (mean ± σ): 4.3 ms ± 12.6 ms [User: 1.1 ms, System: 0.8 ms] | |
Range (min … max): 1.9 ms … 78.8 ms 37 runs | |
Warning: Command took less than 5 ms to complete. Note that the results might be inaccurate because hyperfine can not calibrate the shell startup time much more precise than this limit. You can try to use the `-N`/`--shell=none` option to disable the shell completely. | |
Warning: The first benchmarking run for this command was significantly slower than the rest (78.8 ms). This could be caused by (filesystem) caches that were not filled until after the first run. You should consider using the '--warmup' option to fill those caches before the actual benchmark. Alternatively, use the '--prepare' option to clear the caches before each timing run. | |
Benchmark 4: rg '\w+@' /tmp/a || true | |
Time (mean ± σ): 6.0 ms ± 0.3 ms [User: 4.6 ms, System: 1.0 ms] | |
Range (min … max): 5.7 ms … 7.6 ms 356 runs | |
Summary | |
/tmp/gotest ran | |
1.42 ± 4.18 times faster than rg '\w+@' /tmp/a || true | |
74.51 ± 220.23 times faster than python /tmp/test.py | |
94.18 ± 278.37 times faster than node /tmp/test.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# 'hyperfine' is used to benchmark these programs: | |
# https://github.com/sharkdp/hyperfine | |
# brew install hyperfine | |
# create a test file at /tmp/a composed of 16,000 'a' characters, followed by a newline | |
printf 'a%.0s' {1..16000} > /tmp/a && printf '\n' >> /tmp/a | |
# set up the node program | |
printf "node version: %s\n" "$(node --version)" | |
printf "const { readFileSync } = require('node:fs') | |
readFileSync('/tmp/a').toString().match(new RegExp(/\w+@/))" > /tmp/test.js | |
# set up the python program. I believe that python's 'search' is equivalent to | |
# node's 'match', but it's possible that I'm wrong there. 'match' in python | |
# goes much faster, but only searches for a match of the entire string | |
printf "python version: %s\n" "$(python --version)" | |
printf "import re; re.search(r'\w+@',open('/tmp/a').read())" > /tmp/test.py | |
# set up the go program | |
printf "go version: %s\n" "$(go version)" | |
cat > /tmp/test.go << EOF | |
package main | |
import ( | |
"fmt" | |
"os" | |
"regexp" | |
) | |
func main() { | |
pattern := regexp.MustCompile("\\\\w+@") | |
file, err := os.ReadFile("/tmp/a") | |
if err != nil { | |
fmt.Printf("Error opening file: %v\n", err) | |
return | |
} | |
pattern.FindAll(file, -1) | |
} | |
EOF | |
go build -o /tmp/gotest /tmp/test.go | |
printf "rg version: %s\n" "$(rg --version)" | |
# benchmark each in turn | |
# the '|| true' is because rg won't match the string and reports failure | |
hyperfine "node /tmp/test.js" "python /tmp/test.py" "/tmp/gotest" "rg '\w+@' /tmp/a || true" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment