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

Define copy on SubArray to fallback on getindex #30889

Merged
merged 2 commits into from
Jan 31, 2019

Conversation

mkborregaard
Copy link
Contributor

Defines a fallback function for copy on a SubArray that relegates to getindex. This is under the assumption that the type of a.parent may have an optimised method for getindex defined. In this case it resolves the issue reported here: https://github.com/JuliaLang/julia/issues/21796#issuecomment-456536706 , where @mbauman suggested opening this as a general PR on SubArray. A smaller less impactful change would be to only define it for SubArray{<:SparseMatrixCSC}.
With and without this PR:

using SparseArrays, BenchmarkTools
c = sprand(Bool,6000,18000, 0.01);
d = view(c, 1:6000, rand(1:18000, 1800));
@btime copy($d)
#  2.459 s (8 allocations: 18.59 MiB)

Base.copy(a::SubArray) = a.parent[a.indices...]
@btime copy($d)
#  210.270 μs (6 allocations: 967.27 KiB)

a 10,000x speedup at no cost.
cc @KlausC who told me he was working on something that would have the same implementation for SparseArrays.

base/abstractarray.jl Outdated Show resolved Hide resolved
@fredrikekre fredrikekre added the domain:arrays [a, r, r, a, y, s] label Jan 29, 2019
@mbauman
Copy link
Sponsor Member

mbauman commented Jan 29, 2019

I think this is a very worthwhile change. But I don't think this should be backported as it does have the possibility of changing behaviors for some array types.

A more specific

Base.copy(a::SubArray{<:Any,<:Any,<:SparseArray}) = a.parent[a.indices...]

would be fine to backport as a performance improvement, though.

@mkborregaard
Copy link
Contributor Author

Happy to add that but a bit unsure how to go about it - separate PR adding that? Would that entail changes to this one?

@mbauman
Copy link
Sponsor Member

mbauman commented Jan 29, 2019

No, let's keep this one as-is. I'll defer to @KristofferC and @ararslan on how they'd prefer a backport to look, but it should probably be a separate PR to either master (since the two definitions can gracefully co-exist) or directly into one of their backports branches.

@ararslan
Copy link
Member

A separate PR to master is the easiest.

@mkborregaard
Copy link
Contributor Author

OK - like this? #30895

@mkborregaard
Copy link
Contributor Author

Yay, all tests passed - is there anything more I need to do here (eg add a benchmark somewhere) or is it gtg?

@mbauman mbauman merged commit 0b0a394 into JuliaLang:master Jan 31, 2019
@mbauman mbauman added the kind:potential benchmark Could make a good benchmark in BaseBenchmarks label Jan 31, 2019
@mbauman
Copy link
Sponsor Member

mbauman commented Jan 31, 2019

We don't test this in BaseBenchmarks currently, but we could add a few tests there in the future.

@mkborregaard
Copy link
Contributor Author

Great, thanks a lot for the help with this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:arrays [a, r, r, a, y, s] kind:potential benchmark Could make a good benchmark in BaseBenchmarks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants