You are right. My previous timings were totally wrong anyway, due to a bug I introduced into my program. After fixing it, a fair comparison shows that:
Base.:+{N}(a::NTuple{N}, b::NTuple{N}) = ntuple(i -> a[i] + b[i], Val{N}) is exactly the same speed as the recursive functions I was using. And it is at least 20% faster in my application than the version with N instead of Val{N}. Unfortunately, in my application, the other solution: ((a[i] + b[i] for i = 1:N)...) is extremely slow, and in fact Julia crashes with a segfault before my benchmark finishes (due to using too much memory). So that isn't an option. Anyway, the first solution above is as fast as what I had, and much more convenient. I will go with that for now. Bill. On 10 August 2016 at 18:17, Shashi Gowda <shashigowd...@gmail.com> wrote: > > Base.:+{N}(a::NTuple{N}, b::NTuple{N}) = ntuple(i -> a[i] + b[i], Val{N}) > > should be slightly faster and should not allocate unlike > > Base.:+{N}(a::NTuple{N}, b::NTuple{N}) = ntuple(i -> a[i] + b[i], N) > > > On Wed, Aug 10, 2016 at 8:36 PM, 'Bill Hart' via julia-users < > julia-users@googlegroups.com> wrote: > >> This code seems to be (about 50%) faster than recursive functions: >> >> Base.:+{N}(a::NTuple{N}, b::NTuple{N}) = ntuple(i -> a[i] + b[i], N) >> >> >> But this seems (about 50%) slower: >> >> ((a[i] + b[i] for i = 1:N)...) >> >> >> Anyway, I can use the first method, until I find something faster. It's >> definitely way more convenient. Thanks. >> >> Bill. >> >> >> >> On 10 August 2016 at 16:56, Erik Schnetter <schnet...@gmail.com> wrote: >> >>> The built-in type `CartesianIndex` supports adding and subtracting, and >>> presumably also multiplication. It is implemented very efficiently, based >>> on tuples. >>> >>> Otherwise, to generate efficient code, you might have to make use of >>> "generated functions". These are similar to macros, but they know about the >>> types upon which they act, and thus know the value of `N`. This is a bit >>> low-level, so I'd use this only if (a) there is not other package >>> available, and (b) you have examined Julia's performance and found it >>> lacking. >>> >>> I would avoid overloading operators for `NTuple`, and instead us a new >>> immutable type, since overloading operations for Julia's tuples can have >>> unintended side effects. >>> >>> -erik >>> >>> >>> On Wed, Aug 10, 2016 at 9:57 AM, 'Bill Hart' via julia-users < >>> julia-users@googlegroups.com> wrote: >>> >>>> Does anyone know an efficient way to add NTuples in Julia? >>>> >>>> I can do it using recursive functions, but for various reasons this is >>>> not efficient in my context. I really miss something like tuple(a[i] + b[i] >>>> for i in 1:N) to create the resulting tuple all in one go (here a and b >>>> would be tuples). >>>> >>>> The compiler doesn't do badly with recursive functions for handling >>>> tuples in very straightforward situations, but for example, if I want to >>>> create an immutable type based on a tuple the compiler doesn't seem to be >>>> able to handle the necessary optimisations. At least, that is what I infer >>>> from the timings. Consider >>>> >>>> immutable bill{N} >>>> d::NTuple{N, Int} >>>> end >>>> >>>> and I want to add two bill's together. If I have to add the tuples >>>> themselves using recursive functions, then I no longer seem to be able to >>>> do something like: >>>> >>>> A[i] = B[i] + C[i] efficiently, where A, B and C are arrays whose >>>> elements are of type bill. >>>> >>>> I know how to handle tuples via arrays, but for efficiency reasons I >>>> certainly don't want to do that, e.g. tuple([a[i] + b[i] for i in 1:N]...). >>>> >>>> Bill. >>>> >>> >>> >>> >>> -- >>> Erik Schnetter <schnet...@gmail.com> http://www.perimeterinstitute. >>> ca/personal/eschnetter/ >>> >> >> >