Skip to content

BUG: Excessive temporary memory use in string casts and string operations #33240

Open

Description

@ngoldbaum

Describe the issue:

Some string operations allocate much more temporary memory than their inputs and outputs require, even for arrays containing just one element:

  • StringDType slicing builds an index for the entire input, even when selecting one character.
  • StringDType replacement with an empty pattern sizes its temporary as though every insertion were performed, even with count=1.
  • Some casts allocate buffers for 128 elements regardless of the array's length. Converting one integer to S1048576 has about 130 MiB of peak traced allocations for a 1 MiB output. This also affects operations such as center, ljust, and rjust through internal casts.

These allocations can cause avoidable MemoryErrors or process termination when individual strings or fixed-width string dtypes are large. Temporary storage should be bounded or sized to the work actually required.

Reproduce the code example:

Save as repro.py. This example runs on Linux and macOS. Inputs are created before imposing a limit of 6 MiB above current virtual memory usage; each result needs at most about 1 MiB.

import os
import resource
import subprocess
import sys

import numpy as np

MiB = 1024**2
text = np.array(['x' * MiB], dtype='T')
number = np.array([123])
padded = np.array([b'x'], dtype=f'S{MiB}')
operations = {
    'slice': lambda: np.strings.slice(text, 0, 1),
    'replace': lambda: np.strings.replace(text, '', 'prefix: ', count=1),
    'astype': lambda: number.astype(f'S{MiB}'),
    'center': lambda: np.strings.center(padded, 1),
}

# ps reports virtual memory in KiB on both Linux and macOS.
vsz = int(subprocess.check_output(['ps', '-o', 'vsz=', '-p', str(os.getpid())]))
limit = vsz * 1024 + 6 * MiB
resource.setrlimit(resource.RLIMIT_AS, (limit, limit))

result = operations[sys.argv[1]]()
print('Succeeded')

Run each operation in a separate process:

python repro.py slice
python repro.py replace
python repro.py astype
python repro.py center

Error message:

slice aborts (Linux message shown):

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

replace raises MemoryError: Failed to allocate string in replace. astype and center raise MemoryError.

Python and NumPy Versions:

2.6.0.dev0
3.14.8 (main, Oct  9 2026, 20:43:58) [GCC 14.2.1 20250110 (Red Hat 14.2.1-11)]

Runtime Environment:

Reproduced on Linux aarch64 and macOS arm64 with local NumPy development builds.

How does this issue affect you or how did you find it:

Found while investigating memory use with large individual strings. I plan to submit two PRs using shared memorylimit testing machinery. One PR to use new StringDType slice/replace algorithms, and one to add a byte size limit for casting buffers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions