FiloSottile / age

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.
https://age-encryption.org
BSD 3-Clause "New" or "Revised" License
16.83k stars 492 forks source link

armor: add basic benchmarks #167

Closed codesoap closed 3 years ago

codesoap commented 3 years ago

I wrote this benchmark, so that I could use cd armor && go test -bench=Write -cpuprofile out.prof, because I wanted to find out why encryption with armor is slower than gpg. Unfortunately I came to the conclusion, that most time is spend in the base64 package, so I can't do much here and don't need this benchmark anymore.

I create this pull request anyway, in case it is considered useful for potential future investigations.

FiloSottile commented 3 years ago

How much slower than gpg, and how much slower than without armor? I wouldn't be opposed to using an optimised base64 implementation if it's a significant performance boost. The armor is not in the cryptographic hot path so the complexity is relatively cheap.

codesoap commented 3 years ago

I tried it with an iso of Xubuntu, that I had at hand:

$ du -h xubuntu-18.04.2-desktop-amd64.iso
1.4G    xubuntu-18.04.2-desktop-amd64.iso
$ time age -r age1df9vthfpykfsd4teaehwau7q8pt0f8d6sad22dgerqamnd43t32qzv54e5 xubuntu-18.04.2-desktop-amd64.iso > /dev/null
age -r age1df9vthfpykfsd4teaehwau7q8pt0f8d6sad22dgerqamnd43t32qzv54e5  >   0.85s user 0.49s system 74% cpu 1.801 total
$ time age -a -r age1df9vthfpykfsd4teaehwau7q8pt0f8d6sad22dgerqamnd43t32qzv54e5 xubuntu-18.04.2-desktop-amd64.iso > /dev/null
age -a -r age1df9vthfpykfsd4teaehwau7q8pt0f8d6sad22dgerqamnd43t32qzv54e5  >   37.87s user 40.49s system 87% cpu 1:30.01 total
$ time gpg2 --compress-algo none -r XXX... -o /dev/null --encrypt xubuntu-18.04.2-desktop-amd64.iso
gpg2 --compress-algo none -r XXX... -o     5.67s user 0.89s system 88% cpu 7.398 total
$ time gpg2 --compress-algo none -r XXX... -o /dev/null --armor --encrypt xubuntu-18.04.2-desktop-amd64.iso
gpg2 --compress-algo none -r XXX... -o      20.55s user 1.16s system 76% cpu 28.465 total
codesoap commented 3 years ago

I had just measured these times out of curiosity. I don't really see myself encrypting such large files with -a, so I would prefer to leave the code as is, instead of introducing an external dependency.

FiloSottile commented 3 years ago

Something's off, on my machine (which is arm64 but chacha20poly1305 is pretty good on arm64) BenchmarkChacha20Poly1305/Seal-8192-8 is 859.92 MB/s while BenchmarkEncodeToString-8 is 1377.83 MB/s. chacha20poly1305 + base64 shouldn't be 50 times slower than chacha20poly1305. I'll look into it.

codesoap commented 3 years ago

Thanks for investigating!

I have added SetBytes() calls to the benchmarks (to enable MB/s stats), which confirms that the armor Writer and Reader alone are not the problem:

$ go test -bench=.
goos: openbsd
goarch: amd64
pkg: filippo.io/age/armor
BenchmarkArmorWrite-2             152755              8135 ns/op         503.48 MB/s
BenchmarkArmorRead-2              249819              4935 ns/op          73.76 MB/s
PASS
ok      filippo.io/age/armor    3.657s
codesoap commented 3 years ago

Pefromance looks good now (age with armor is now even slightly faster than gpg without armor for me):

$ time age -a -r age1df9vthfpykfsd4teaehwau7q8pt0f8d6sad22dgerqamnd43t32qzv54e5 xubuntu-18.04.2-desktop-amd64.iso > /dev/null
age -a -r age1df9vthfpykfsd4teaehwau7q8pt0f8d6sad22dgerqamnd43t32qzv54e5  >   5.46s user 1.74s system 97% cpu 7.389 total

Thanks for the fix!

FiloSottile commented 3 years ago

Awesome! Thank you for bringing it up ✨