This is a modified version of the standard base64 decoder from encoding/base64
. Key differences:
- Accepts both Standard and URL-safe encoding, no need to specify it explicitly.
- Works for both padded and raw inputs.
- The input can be a
string
or a[]byte
, no allocation or copy is performed for either.
The goal was to create a decoder compatible with the one used in nodejs (and possibly elsewhere too). Unfortunately the standard package does not expose enough API to do this efficiently, and trying all 4 possible variants (standard/url, padded/raw) seemed wasteful.
Because there is no need to convert the input from string
to []byte
, decoding strings (specially long ones)
is more efficient than with the standard library. Below is the comparison between BenchmarkDecodeBase64Std
and BenchmarkDecodeBase64
on go1.21.3:
goos: linux
goarch: amd64
pkg: base64dec
cpu: Intel(R) Core(TM) i7-2600S CPU @ 2.80GHz
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
DecodeBase64/2-8 28.85n ± 3% 22.95n ± 2% -20.45% (p=0.000 n=10)
DecodeBase64/4-8 48.05n ± 0% 41.41n ± 1% -13.83% (p=0.000 n=10)
DecodeBase64/8-8 38.31n ± 2% 29.55n ± 1% -22.89% (p=0.000 n=10)
DecodeBase64/64-8 406.7n ± 5% 113.0n ± 2% -72.20% (p=0.000 n=10)
DecodeBase64/8192-8 31.670µ ± 10% 9.995µ ± 2% -68.44% (p=0.000 n=10)
geomean 232.8n 126.0n -45.89%
│ old.txt │ new.txt │
│ B/s │ B/s vs base │
DecodeBase64/2-8 132.2Mi ± 3% 166.2Mi ± 2% +25.70% (p=0.000 n=10)
DecodeBase64/4-8 158.8Mi ± 0% 184.2Mi ± 1% +16.04% (p=0.000 n=10)
DecodeBase64/8-8 298.7Mi ± 2% 387.3Mi ± 1% +29.67% (p=0.000 n=10)
DecodeBase64/64-8 206.4Mi ± 5% 742.4Mi ± 2% +259.71% (p=0.000 n=10)
DecodeBase64/8192-8 329.0Mi ± 11% 1042.4Mi ± 2% +216.87% (p=0.000 n=10)
geomean 211.8Mi 391.4Mi +84.81%
│ old.txt │ new.txt │
│ B/op │ B/op vs base │
DecodeBase64/2-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
DecodeBase64/4-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
DecodeBase64/8-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
DecodeBase64/64-8 96.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10)
DecodeBase64/8192-8 12.00Ki ± 0% 0.00Ki ± 0% -100.00% (p=0.000 n=10)
geomean ² ? ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean
│ old.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
DecodeBase64/2-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
DecodeBase64/4-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
DecodeBase64/8-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
DecodeBase64/64-8 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10)
DecodeBase64/8192-8 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10)
geomean ² ? ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean