bech32

Pure Haskell bech32, bech32m encoding/decoding (docs.ppad.tech/bech32).
git clone git://git.ppad.tech/bech32.git
Log | Files | Refs | README | LICENSE

commit 95c41c2a1064d3b433bfe6d0087a2f4776b00c23
parent 5909ce98c22a1a82465b4f806e70df426f89f070
Author: Jared Tobin <jared@jtobin.io>
Date:   Tue, 23 Dec 2025 08:40:47 -0330

meta: add llvm flag

Diffstat:
MREADME.md | 25++++++++++---------------
Mflake.nix | 5+++--
Mppad-bech32.cabal | 7+++++++
3 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md @@ -43,33 +43,28 @@ Haddocks (API documentation, etc.) are hosted at ## Performance -The aim is best-in-class performance for pure, highly-auditable Haskell -code. At present we're a little over twice as fast as the official -BIP173 reference implementation. +The aim is best-in-class performance for pure Haskell code. Current benchmark figures on a M4 Silicon MacBook Air look like (use `cabal bench` to run the benchmark suite): ``` benchmarking benchmarks/ppad-bech32/bech32 encode/120b - time 783.5 ns (781.4 ns .. 786.6 ns) + time 462.7 ns (460.8 ns .. 465.5 ns) 1.000 R² (1.000 R² .. 1.000 R²) - mean 791.1 ns (788.7 ns .. 793.5 ns) - std dev 8.193 ns (7.461 ns .. 8.973 ns) + mean 465.5 ns (464.3 ns .. 466.6 ns) + std dev 3.955 ns (3.485 ns .. 4.602 ns) benchmarking benchmarks/ppad-bech32/bech32 decode/120b - time 944.0 ns (943.1 ns .. 944.7 ns) + time 499.4 ns (497.5 ns .. 502.3 ns) 1.000 R² (1.000 R² .. 1.000 R²) - mean 942.4 ns (941.7 ns .. 943.1 ns) - std dev 2.197 ns (1.838 ns .. 2.669 ns) - - benchmarking benchmarks/reference/bech32 encode/120b - time 1.282 μs (1.281 μs .. 1.283 μs) - 1.000 R² (1.000 R² .. 1.000 R²) - mean 1.282 μs (1.282 μs .. 1.283 μs) - std dev 1.338 ns (996.0 ps .. 1.881 ns) + mean 508.0 ns (505.2 ns .. 510.8 ns) + std dev 9.101 ns (7.828 ns .. 11.23 ns) + variance introduced by outliers: 21% (moderately inflated) ``` +You should compile with the 'llvm' flag for maximum performance. + ## Security This library aims at the maximum security achievable in a diff --git a/flake.nix b/flake.nix @@ -18,6 +18,7 @@ pkgs = import nixpkgs { inherit system; }; hlib = pkgs.haskell.lib; + llvm = pkgs.llvmPackages_15.llvm; hpkgs = pkgs.haskell.packages.ghc981.extend (new: old: { ${lib} = old.callCabal2nixWithOptions lib ./. "--enable-profiling" {}; @@ -38,10 +39,9 @@ buildInputs = [ cabal cc + llvm ]; - inputsFrom = builtins.attrValues self.packages.${system}; - doBenchmark = true; shellHook = '' @@ -50,6 +50,7 @@ echo "cc: $(${cc}/bin/cc --version)" echo "ghc: $(${ghc}/bin/ghc --version)" echo "cabal: $(${cabal}/bin/cabal --version)" + echo "llc: $(${llvm}/bin/llc --version | head -2 | tail -1)" ''; }; } diff --git a/ppad-bech32.cabal b/ppad-bech32.cabal @@ -14,6 +14,11 @@ description: bech32 and bech32m encoding/decoding on strict bytestrings, per BIPs 173 & 350. +flag llvm + description: Use GHC's LLVM backend. + default: False + manual: True + source-repository head type: git location: git.ppad.tech/bech32.git @@ -23,6 +28,8 @@ library hs-source-dirs: lib ghc-options: -Wall + if flag(llvm) + ghc-options: -fllvm -O2 exposed-modules: Data.ByteString.Base32 , Data.ByteString.Bech32.Internal