Le lundi 05 janvier 2015 à 18:53 -0800, Greg Plowman a écrit : > > The only reason I can think of is that a copy may be > costly for certain > types, and it's not needed in most cases since the > summation will create > a new value in the general case. But as you noted this > is not true when > the array only contains one element. So it looks like > the most efficient > fix would be to copy only when n == 1 in > _mapreduce(). > > > > I must admit I don't really understand the code, however it doesn't > look like evaluation would be affected for n>=2. > The extra cost would only be for 1-element arrays: > > > Apparently, for 1-element arrays, zero(::MyType) needs to be defined > For 0-element arrays, both zero(::MyType) and zero(::Type{MyType}) > need to be defined > (strangely, for 0-element arrays, mr_empty() calls r_promote(::AddFun, > zero(T)) which effectively calls zero(T) + zero(zero(T)), so both > forms of zero() need to be defined Yes, but that's not an issue as the definitions are equivalent: zero(x::Number) = oftype(x,0) zero{T<:Number}(::Type{T}) = convert(T,0)
help?> oftype Base.oftype(x, y) Convert "y" to the type of "x" ("convert(typeof(x), y)"). > In any case, at the moment I guess I have 2 workarounds: > > > I could define MyType as a subtype of Number and provide zero() > functions. > However, I'm not sure what the side effects of subtyping are, and > whether this is advisable? I don't think it would be a problem, it may well make a lot of sense if your type is similar to a number (which is apparently the case since you can sum it). > > type MyType <:Number > x::Int > end > > Base.zero(::Type{MyType}) = MyType(0) # required for sum(0-element > array) > Base.zero(::MyType) = MyType(0) # required for sum(0-element > array) and sum(1-element array) > > +(a::MyType, b::MyType) = MyType(a.x + b.x) > > > > > Alternatively, I could define my own sum() functions, but then if I > want the general functionality of all variants of sum(), this seems > non-trivial. Indeed. Another solution is to make a pull request with a possible fix, it could be included quite soon in a 0.3.x minor release so that you can use it. Regards