Skip to content

Performance Optimization: Use toarray() instead of np.asarray(todense()) #124

Description

@SaFE-APIOpt

sparse_data = sparse.csr_matrix(data, shape=shape)

Hi, I’d like to suggest a minor optimization based on the internal implementation of sparse-to-dense conversions.
Current pattern:

sparse_data = sparse.csr_matrix(data, shape=shape)
np_values = np.squeeze(np.asarray(sparse_data.todense()))

Suggested replacement:
np_values = np.squeeze(sparse_data.toarray())

  1. sparse.todense() returns a numpy.matrix object.
    This is a legacy type in NumPy with different operator semantics (* means matrix multiplication, not element-wise). While np.asarray(...) wraps it, it doesn’t eliminate matrix-specific behaviors unless explicitly copied or converted, which introduces subtle performance and correctness risks.

  2. np.asarray(...) adds unnecessary overhead.
    Calling np.asarray on a numpy.matrix still requires type checking and often incurs an additional function call stack. It doesn’t simplify the type structure, but merely suppresses copying. This leads to a verbose and slightly less performant pipeline.

  3. sparse.toarray() is the clean, modern alternative.
    It directly creates a numpy.ndarray from the sparse structure using C-level memory allocation, avoiding the intermediate matrix object entirely. Internally, this path is optimized and aligned with NumPy’s preferred dense representation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions