Skip to main content

Crate memspan

Crate memspan 

Source
Expand description

memspan

SIMD-accelerated byte-class scanning for lexers and parsers.

github LoC Build codecov

docs.rs crates.io crates.io license

English | 简体中文

§Quick start

let src = b"   hello, world";

// Skip leading whitespace — dispatches to AVX2 / NEON / SIMD128 at runtime.
let n = memspan::skip_whitespace(src);
assert_eq!(n, 3);

// Find the first comma.
let comma = memspan::skip_until(src, b',');
assert_eq!(comma, Some(8));

§Overview

memspan provides zero-allocation, no_std-compatible functions to skip, count, and locate bytes in ASCII character classes, dispatching to the best available SIMD backend at runtime:

ArchitectureDispatch order
x86_64AVX-512BW → AVX2 → SSE4.2 → scalar
x86SSE4.2 → scalar
aarch64NEON → scalar
wasm32SIMD128 → scalar
otherscalar

§Installation

[dependencies]
memspan = "0.1"

For no_std without an allocator:

[dependencies]
memspan = { version = "0.1", default-features = false }

§Built-in classes

All class functions return the byte length of the longest matching prefix.

FunctionMatches
skip_whitespace , \t, \r, \n
skip_digits09
skip_hex_digits09, af, AF
skip_octal_digits07
skip_binary0, 1
skip_alphaaz, AZ
skip_alphanumericaz, AZ, 09
skip_ident_startaz, AZ, _
skip_identaz, AZ, 09, _
skip_loweraz
skip_upperAZ
skip_ascii0x000x7F
skip_non_ascii0x800xFF
skip_ascii_graphic0x210x7E (printable non-space)
skip_ascii_control0x000x1F, 0x7F

§Generic operations

skip_while, skip_until, count_matches, and find_last accept any Needles value — a single u8, a fixed-size array [u8; N], or a &[u8] slice:

// Skip while any of several bytes match.
let n = memspan::skip_while(b"  ,\t ok", [b' ', b',', b'\t']);
assert_eq!(n, 5);

// Find the first occurrence of any needle — like memchr but multi-byte.
let pos = memspan::skip_until(b"hello\nworld", b'\n');
assert_eq!(pos, Some(5));

// Count every newline in a buffer.
let lines = memspan::count_matches(b"a\nb\nc\n", b'\n');
assert_eq!(lines, 3);

// Find the rightmost match.
let last = memspan::find_last(b"\"hello\"", b'"');
assert_eq!(last, Some(6));

§Custom classes with skip_class!

Define your own byte class and get the same SIMD dispatch as the built-ins:

memspan::skip_class! {
    /// Skip whitespace and commas.
    pub fn skip_ws_and_comma(bytes = [b' ', b'\t', b'\r', b'\n', b',']);
}

memspan::skip_class! {
    /// Skip lowercase ASCII letters.
    pub fn skip_lowercase(ranges = [b'a'..=b'z']);
}

memspan::skip_class! {
    /// Skip alphanumeric plus common punctuation.
    pub fn skip_punct_ident(
        bytes  = [b'_', b'-', b'!', b'?'],
        ranges = [b'a'..=b'z', b'A'..=b'Z', b'0'..=b'9'],
    );
}

assert_eq!(skip_ws_and_comma(b"  , ok"), 4);
assert_eq!(skip_lowercase(b"abcXYZ"), 3);
assert_eq!(skip_punct_ident(b"hello-world! 42"), 12);

§Benchmarks

Throughput in GiB/s across input sizes, measured on GitHub Actions runners (2026-04-22, --quick Criterion runs). Environments: aarch64 — macOS-latest (ARM64, NEON); x86_64 — ubuntu-latest (X64, runtime AVX2 detection).

§aarch64 — NEON

Function16 B32 B64 B256 B4 KiB64 KiB
skip_binary1.97.010.923.139.534.9
skip_octal_digits2.27.312.327.541.045.9
skip_digits2.27.310.626.739.944.8
skip_hex_digits1.84.16.414.821.823.5
skip_alpha2.35.810.423.132.637.6
skip_alphanumeric1.84.36.814.919.723.1
skip_ident_start1.53.46.112.524.423.3
skip_ident1.33.85.613.216.617.8
skip_whitespace1.94.57.015.220.219.0

§aarch64 — scalar fallback

Function16 B32 B64 B256 B4 KiB64 KiB
skip_binary2.32.11.91.82.02.0
skip_octal_digits1.72.22.01.92.12.1
skip_digits1.92.32.22.32.42.2
skip_hex_digits1.71.41.51.51.21.3
skip_alpha2.32.52.21.91.91.9
skip_alphanumeric1.81.81.71.51.61.6
skip_ident_start1.91.91.91.71.92.0
skip_ident1.51.61.51.51.61.6
skip_whitespace1.41.61.81.61.81.8

§x86_64 — AVX2

Function16 B32 B64 B256 B4 KiB64 KiB
skip_binary2.02.54.715.860.788.4
skip_octal_digits2.02.54.716.362.362.8
skip_digits2.02.54.716.363.280.9
skip_hex_digits1.41.73.110.333.238.3
skip_alpha2.02.54.314.659.968.6
skip_alphanumeric1.51.73.210.631.637.5
skip_ident_start1.51.73.311.139.746.3
skip_ident1.81.62.99.928.433.8
skip_whitespace1.92.54.413.738.246.5

§x86_64 — scalar fallback

Function16 B32 B64 B256 B4 KiB64 KiB
skip_binary2.32.52.12.73.03.0
skip_octal_digits2.22.42.12.63.03.0
skip_digits2.12.52.12.73.03.0
skip_hex_digits1.41.51.21.41.51.5
skip_alpha2.11.81.81.71.81.8
skip_alphanumeric1.31.41.21.41.51.5
skip_ident_start1.31.41.21.41.51.5
skip_ident1.31.41.31.41.51.5
skip_whitespace1.81.51.31.92.02.0

§Generic dispatch (skip_until / skip_while)

FunctionBackend16 B32 B64 B256 B4 KiB64 KiB
skip_untilaarch64 NEON0.51.12.57.115.517.0
skip_untilaarch64 scalar1.41.61.51.41.61.6
skip_untilx86_64 AVX20.50.71.34.925.836.9
skip_untilx86_64 scalar0.90.90.91.01.01.0
skip_whileaarch64 NEON0.71.53.08.616.316.7
skip_whileaarch64 scalar1.71.92.01.92.02.1
skip_whilex86_64 AVX20.70.81.45.226.637.1
skip_whilex86_64 scalar1.11.11.01.11.21.2

§skip_class! macro vs skip_while

Backend16 B32 B64 B256 B4 KiB64 KiB
skip_class! macroaarch64 NEON2.04.46.913.516.718.2
skip_while (array)aarch64 NEON0.71.43.08.815.117.6
skip_class! macrox86_64 AVX21.72.44.313.635.841.7
skip_while (array)x86_64 AVX20.70.81.45.226.437.8

§Features

FeatureDefaultDescription
stdLink against the standard library
allocEnable heap allocation without std
(neither)Pure no_std / no_alloc
§License

memspan is dual-licensed under the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE, LICENSE-MIT for details.

Copyright (c) 2026 Al Liu.

Re-exports§

pub use skip::*;

Modules§

skip
SIMD-accelerated skipping utilities for lexing.
utils
Utilities for SIMD-accelerated lexing, including CPU feature detection.

Macros§

skip_class
Define a custom skip_* function for an ASCII byte class, generating the same scalar fallback + SIMD loop the built-in skip::skip_digits, skip::skip_whitespace, etc. use internally. On x86/x86_64 the generated function dispatches through AVX2 (256-bit) → SSE4.2 (128-bit) → scalar; on aarch64 through NEON; on wasm32 through SIMD128.

Traits§

Needles
Needle types for SIMD-accelerated searching.