Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: sparse: speed up LIL indexing + assignment via Cython #3356

Merged
merged 8 commits into from
Feb 24, 2014

Conversation

pv
Copy link
Member

@pv pv commented Feb 19, 2014

This PR gains 5...50x speedups in LIL matrix setitem/getitem by writing the fancy indexing code more carefully. I also add fast paths for scalar indexing (~5x faster).

The fancy getitem speed is now not far from CSR/CSC. Fancy setitem is also not far from CSR/CSC (and for changing sparsity pattern, LIL can now be much faster than CSR/CSC).

Benchmarks: https://gist.githubusercontent.com/pv/9102868/raw/a256bfe058b44131f8acba0f41ab90eafacbe127/gistfile1.txt

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling c5e3ae4 on pv:lil-speed-cy into 32cd96d on scipy:master.

@jnothman
Copy link
Contributor

I think you can switch off bounds checking and wraparound for a few more functions...

@pv
Copy link
Member Author

pv commented Feb 20, 2014

I didn't get measureable performance improvement out from disabling wraparound/bounds. bisect_left however does matter, as it's the innermost loop.

It's also possible someone passes in wrong sized rows/data arrays, so if I add the decorators, more checks would be needed. I'd rather keep it simpler.

@jnothman
Copy link
Contributor

Okay.

On 20 February 2014 11:09, Pauli Virtanen notifications@github.com wrote:

I didn't get any measureable performance improvement out from disabling
wraparound/bounds. bisect_left however does matter, as it's the innermost
loop.

It's also possible someone passes in wrong sized rows/data arrays, so if I
add the decorators, more checks would be needed. I'd rather keep it simpler.

Reply to this email directly or view it on GitHubhttps://github.com//pull/3356#issuecomment-35567998
.

@@ -30,6 +30,7 @@ scipy/io/matlab/mio_utils.c binary
scipy/io/matlab/mio5_utils.c binary
scipy/io/matlab/streams.c binary
scipy/signal/_spectral.c binary
scipy/sparse/_csparsetools.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that should have gone into .gitignores?

aren't the gitattributes for the cython files are now obsolete as they are not included in the repository anymore?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I intended to put it to gitignore. Fixed.

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling fee97bd on pv:lil-speed-cy into 32cd96d on scipy:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling fee97bd on pv:lil-speed-cy into 32cd96d on scipy:master.

@rgommers
Copy link
Member

@jnothman did you finish your review? This could still make it into 0.14.x if merged in time.

# Scalar fast path first
if isinstance(index, tuple) and len(index) == 2:
i, j = index
if ((isinstance(i, int) or isinstance(i, np.integer)) and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other implementations use sputils.isintlike which has slightly different semantics. For consistency, it should apply here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using isintlike or isscalarlike slows the fast path down by 25-50%.
Hence the splitting of it into two parts.

@jnothman
Copy link
Contributor

Sorry for so many minor comments. Really, none should be a blocker, and this LGTM!

As per review comments:

- explain and rename prepare_index_arrays
- indicate out-of-bounds column indices
- faster insertion in lil_fancy_get
- explain reason for preferring isinstance in scalar fast paths
@pv
Copy link
Member Author

pv commented Feb 24, 2014

Thanks, revised. Getitem is now ~25% faster due to the faster insertion.

@jnothman
Copy link
Contributor

Great! I hope you haven't missed the 0.14 boat :)

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling 6270da3 on pv:lil-speed-cy into 0da153e on scipy:master.

@rgommers
Copy link
Member

To make sure no boats are missed, let's push the merge button.

rgommers added a commit that referenced this pull request Feb 24, 2014
ENH: sparse: speed up LIL indexing + assignment via Cython
@rgommers rgommers merged commit 6bea3d0 into scipy:master Feb 24, 2014
@rgommers
Copy link
Member

Thanks @pv, @jnothman

@rgommers rgommers added this to the 0.14.0 milestone Feb 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A new feature or improvement scipy.sparse
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants