Use NumPy string functions inside Numba-compiled code.
charex lets @njit functions call common NumPy string operations such as
comparisons, find, startswith, endswith, str_len, and string predicates.
It works with fixed-width NumPy string arrays and, on NumPy 2.x, variable-width
StringDType arrays.
The PyPI distribution is named charex-numba; the import package is charex:
python -m pip install charex-numbaimport charex
import numpy as np
from numba import njit
@njit
def count_long(values, min_length):
# charex enables this NumPy string operation inside nopython mode.
lengths = np.strings.str_len(values)
return np.count_nonzero(lengths >= min_length)On NumPy 1.x, use the same pattern with np.char and fixed-width S or U
arrays.
NumPy behavior is the contract. Supported operations aim to match NumPy's return values, output shapes, dtypes, exception behavior, broadcasting, and input immutability.
Comparisons:
equalnot_equalgreatergreater_equallessless_equal
Occurrence and search:
countstartswithendswithfindrfindindexrindex
Information and predicates:
str_lenisalphaisalnumisdigitisdecimalisnumericisspaceislowerisupperistitle
Additional np.char operation:
compare_chararrays
np.charfixed-width byte strings:Snp.charfixed-width Unicode strings:Unp.stringsfixed-width byte strings:Snp.stringsfixed-width Unicode strings:Unp.stringsvariable-width Unicode strings:StringDType
NumPy stores S and U arrays in fixed-size records. StringDType is
variable-width and stores string payloads separately from the array's fixed-size
metadata records. charex supports both storage models.
The native charex._stringdtype extension is required for StringDType support
and is built by the package install.
Supported inputs include scalars, 0-D arrays, 1-D arrays, N-D arrays, and
broadcast-compatible shapes for both fixed-width S/U and variable-width
StringDType. Array inputs may be contiguous, read-only, positively strided,
negatively strided, zero-stride, or empty views.
StringDType() and StringDType(na_object=...) variants are supported for the
listed np.strings operations with NumPy-matching operation-specific null
behavior.
np.char and np.strings are not treated as aliases. For example, np.char
comparison semantics strip trailing whitespace/NULs, while np.strings
comparison semantics do not.
Byte inputs to Unicode-only predicates such as isdecimal and isnumeric
follow NumPy and raise unsupported-loop errors.
charex does not yet implement transformation or output-producing string
operations such as replace, case conversion, strip, pad, join, split, encode, or
decode. Object arrays and object-scalar bridges are also outside the current
nopython string path.
On the current Numba 0.65.1 matrix, charex ranges from 1.02x to 6.51x
NumPy speed across 135 fixed-width and StringDType cases, with a 1.60x
median.
Benchmark artifacts are in docs/benchmarks/numba-v-0.65.1.
The previous Numba 0.59 matrix is archived under benchmarks/numba-v-0.59.
charex targets Numba 0.65.1 and the NumPy ranges tested by that Numba release:
- Python
>=3.10,<3.15 - Numba
>=0.65.1,<0.66 - NumPy
>=1.22,<1.27or>=2.0,<2.5 - llvmlite
0.47.x
np.strings is available on NumPy 2.x only. On NumPy 1.x, charex registers the
np.char overloads and skips np.strings.
Install test dependencies:
python -m pip install -e ".[test]"Run tests:
pytest -qRun the representative behavior audit:
python docs/exploration/string_array_shape_audit.py --methods representative --api all --dtype allRun the benchmark smoke test:
python benchmarks/benchmark.py --size 50000 --repeat 5Install benchmark plotting dependencies and write CSV/PNG output:
python -m pip install -e ".[bench]"
python benchmarks/benchmark.py --size 50000 --repeat 5 --plotRegenerate the full benchmark matrix from the repository root:
python -m pip install -e ".[bench]"
# Use a fresh NUMBA_CACHE_DIR for release matrices
CACHE_DIR=$(mktemp -d /tmp/charex-numba-cache.XXXXXX)
NUMBA_CACHE_DIR="$CACHE_DIR" PYTHONPATH=. \
python benchmarks/matrix.py --size 250000 --repeat 15CI runs Python 3.10-3.14 across representative NumPy 1.x and 2.x jobs with Numba 0.65.1. The benchmark matrix above was generated on Python 3.12.8, NumPy 2.4.6, Numba 0.65.1, and llvmlite 0.47.0.










