-
Notifications
You must be signed in to change notification settings - Fork 149
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
Performance of splatting a SVector #361
Comments
I'm just a curious bystander, but does your actual use case involve a possibly multi-dimensional |
@tkoolen I've changed the example to the simpler Tuple()... which seems just as fast. So the question would be if we could convert to a Tuple before splatting to increase performance. With regards to my specific use case (out of scope for this issue): It does involve multi-dimensional arrays, which I don't want to reshape and thus sometimes index Vectors with indices of multi-dimensional arrays of the same length. I'd like it to work for any N dimensional array, so I'd rather not write any dimension specific code. Splatting is a very good fit for this use case. |
Just ran into that. Apparently splatting goes through iteration, so maybe static arrays don't implement fully the iteration protocol? I tried monkey-patching the only missing method that I've seen, with |
Splatting of julia> foo(A, I) = A[I...]
foo (generic function with 1 method)
julia> foo(rand(10,10), SVector(1,2))
0.9605820417688018
julia> @code_warntype foo(rand(10,10), SVector(1,2))
Body::Float64
1 ─ %1 = (Core.tuple)(A)::Tuple{Array{Float64,2}}
│ %2 = (Core._apply)(Base.getindex, %1, I)::Float64
└── return %2
julia> @code_warntype foo(rand(10,10), (1,2))
Body::Float64
1 ─ %1 = (getfield)(I, 1)::Int64
│ %2 = (getfield)(I, 2)::Int64
│ %3 = (Base.arrayref)(true, A, %1, %2)::Float64
└── return %3 I guess this probably needs changes in the compiler. |
Related
It looks like people have suggested both tweaking lowering and teaching inference more about Where [Edit: |
I have to admit, I don't think I understand The splat lowering idea is interesting. I also wonder if we can give the compiler the information it needs - for example, could be safe to see if inference can infer |
I suspect we can't get around this in StaticArrays itself, we really need compiler support either in lowering or inference. See the hardcoded test at |
I'm not sure whether this is a useful contribution because it's the first You could define something like this: @generated function static_splat(f::Function, v::SVector{S, T}) where {S, T}
expr = Expr(:call, :f)
for i in 1:S
push!(expr.args, :(v[$i]))
end
return expr
end And perform splatting for cases where the splatted vector is the only argument to the function like in this example: V = @SVector [(@SVector [1,2]), (@SVector[3,4])]
V_matrix = static_splat(hcat, B) For some cases this is good enough. I don't know enough about meta programming in Julia to come up with a better way to do this. Maybe there is also a nice Macro-way of doing this. Also, maybe simply doing |
Hi @lassepe! That generated function looks correct, though it's not really necessary to use a generated function for this. I think the better workaround is to just use If you do want to automate the splat_args(x) = x
splat_args(x::StaticVector) = Tuple(x)
macro splat(ex)
# A fun exercise for the reader :-)
end
@splat hcat(a, bs..., c, ds...)
# transform that hcat syntax into
hcat(a, splat_args(bs)..., c, splat_args(ds)...) This works for any type (other types can easily extend |
Is this still relevant after JuliaLang/julia#36684? |
Indeed that upstream fix is the one we needed :-) |
It seems that splatting could be very fast, as the size is known beforehand. On julia 0.6.2 however, the following code;
gives the following results:
It seems that indexing with an SVector is several factors slower than normal indexing in this case.
I've used a workaround by converting an SVector to a NTuple first and wrapping it in an CartesianIndex for this specific use case, which brings the performance back within normal bounds.
I'm not sure where to optimize this, or whether this is some compiler specific issues that we can't workaround. At the least a warning in the documentation could be given not to splat SVectors (and related types).
The text was updated successfully, but these errors were encountered: