elm-cardano/x-bytes/1.1.0

elm-cardano/x-bytes

Fast hex encoding/decoding and comparable byte sequences for Elm.

Modules

Hex

Convert between Bytes and hexadecimal strings.

import Hex

Hex.fromBytes bytes       -- Bytes -> String
Hex.toBytes "deadbeef"    -- String -> Maybe Bytes
Hex.toBytesUnchecked hex  -- String -> Bytes (no validation)

XBytes

Comparable byte sequences backed by a lowercase hex string. Unlike Bytes, two XBytes values can be compared with ==.

import XBytes

XBytes.fromHex "DeadBeef"  -- Maybe XBytes (validates + lowercases)
XBytes.toHex xb            -- String
XBytes.fromBytes bytes     -- XBytes
XBytes.toBytes xb          -- Bytes

Plus common operations: append, concat, slice, reverse, left, right, dropLeft, dropRight, join, width, and JSON / Bytes.Encode / Bytes.Decode interop. See the module docs for the full API.

Install

elm install elm-cardano/x-bytes

Performance

Performance is a first-class concern for this package. Every function has been benchmarked and optimized, with multiple implementation strategies tested and compared. Here are the key techniques:

  • Batched decoding: Hex.fromBytes reads 20 bytes per loop iteration (via Decode.map5 over Int32) and maps each byte through a 256-entry case jump table (compiled to a V8 O(1) switch). Hex.toBytes parses 8 hex characters at a time, packing 4 bytes into Int32 words to reduce encoder list length by 4x.
  • Allocation-free validation: XBytes.fromHex validates hex characters without allocating intermediate Bytes or Encoder nodes, then applies a single native String.toLower call. Benchmarked 25-43% faster than routing through Hex.toBytes.
  • ConsString-aware accumulation: String concatenation with (++) is O(1) in V8 (creates a rope node), which we exploit throughout. XBytes.concat uses List.foldl with (++) instead of building an intermediate list, benchmarked 63% faster.
  • Sentinel-based error signaling: Hex digit parsing returns -1 instead of Nothing, eliminating one Just allocation per hex pair (2048 saved for 1024 bytes).

As a reference point, here is how our Hex module compares to jxxcarlson/hex (the most popular Elm hex package):

FunctionSizeelm-cardano/x-bytesjxxcarlson/hexSpeedup
fromBytes32 B518 ns2,345 ns4.5x
fromBytes256 B4,146 ns18,321 ns4.4x
fromBytes1024 B17,880 ns77,491 ns4.3x
toBytes32 B635 ns1,171 ns1.8x
toBytes256 B4,232 ns8,162 ns1.9x
toBytes1024 B16,191 ns34,398 ns2.1x

See bench/ for the full benchmarking setup and methodology. See optimization-report.md for the history of attempted optimizations.

Development

pnpm install
pnpm test           # run tests
pnpm review         # elm-review
pnpm format:check   # check formatting
pnpm bench:build    # build benchmarks
pnpm bench:test     # run benchmark correctness checks