-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
bsxfun performance issue #2991
Comments
I tested this in MATLAB as tic; bsxfun(@minus, a, b); toc This takes |
Could the order of accessing elements of Also, have you tried a comprehension to see how it performs? For me function subcol_compr{T<:Real}(a::Matrix{T},b::Vector{T})
[a[i,j] - b[i] for i in 1:size(a,1), j in 1:size(a,2)]
end is as fast as the for loop. Matlab programmers may instinctively use bsxfun - I don't know because it has been decades since I have programmed in Matlab - but the julian approach to many such calculations should be to use a comprehension I would think. |
The list comprehension version is slightly faster than the for-loop. This is not big deal for me. I can devectorize such calculations (or use comprehensions) if they sit in the way of a critical path. However, it would still be nice to have a |
I also would like to have a good |
The comprehension solution is somewhat inconvenient, because it can surprise you with its choice of result type. The function subcol_compr() as declared above, returns a Matrix as one would want and expect, but the same code without type specifiers returns a clunky Array{Any}:
In contrast, bsxfun returns a Matrix{Float64} as desired:
|
@bsxfan if you put the comprehension statement inside a function, it would return an instance of function subcol_compr{T<:Real}(a::Matrix{T},b::Vector{T})
[a[i,j] - b[i] for i in 1:size(a,1), j in 1:size(a,2)]
end
A = randn(2, 3)
b = randn(2)
subcol_compr(A, b) # this returns Array{Float64, 2} The thing is that Julia treats global variable differently in terms of type inference. So you see different results when you write the list comprehension at top level and within a function. Or, you can make it work with global variables in the following way Float64[a[i,j] - b[i] for i in 1:size(a,1), j in 1:size(a,2)] This is explained in the Notes here: http://docs.julialang.org/en/release-0.1/manual/arrays/#comprehensions |
@toivoh worth closing this? |
Yes, this should be fixed with |
Issue #1838 mentioned the performance issue of
bsxfun
when there are more than three arguments. However, I found that when in common cases where there are only two arguments,bsxfun
is also considerably slower.Here is the code to show this issue:
The output on my macbook pro (using latest Julia commit) is
So,
bsxfun
is 3x slower. Considering that there are 10^8 elements ina
, the overhead ofbsxfun
in figuring out shapes is unlikely to be the main culprit here. It is likely that the inner loop ofbsxfun
is not as efficient as the hand crafted one.The text was updated successfully, but these errors were encountered: