Re: [julia-users] Adding tuples
Ah, ok. Thanks for clarifying this. We probably have the optimum for now. There are other things we can do in our application to get better performance anyway, so we'll focus on those now. Thanks for all the help! Bill. On 12 August 2016 at 13:46, Kristoffer Carlssonwrote: > > Since they are mutable (I assume) > > They are not. They are basically wrappers around a tuple with conveniently > defined methods on them to make them act like vectors / matrices. You > cannot in Julia store mutable objects inline in an array. > > On Friday, August 12, 2016 at 1:22:44 PM UTC+2, Bill Hart wrote: >> >> Awesome, I didn't realise this. I will definitely give them a try (and >> possibly eventually report back). It very likely makes more sense for our >> application for us to use these than an immutable tuple. Since they are >> mutable (I assume), we can pass them as an argument to a function to be >> written to (as output). Of course I realise there are many applications >> where the immutable tuples are better. >> >> Bill. >> >> On 12 August 2016 at 12:12, Kristoffer Carlsson >> wrote: >> >>> They are bitstypes so if you have a vectoe of them they will be stored >>> "inline" in the vector. >> >> >>
Re: [julia-users] Adding tuples
> Since they are mutable (I assume) They are not. They are basically wrappers around a tuple with conveniently defined methods on them to make them act like vectors / matrices. You cannot in Julia store mutable objects inline in an array. On Friday, August 12, 2016 at 1:22:44 PM UTC+2, Bill Hart wrote: > > Awesome, I didn't realise this. I will definitely give them a try (and > possibly eventually report back). It very likely makes more sense for our > application for us to use these than an immutable tuple. Since they are > mutable (I assume), we can pass them as an argument to a function to be > written to (as output). Of course I realise there are many applications > where the immutable tuples are better. > > Bill. > > On 12 August 2016 at 12:12, Kristoffer Carlsson> wrote: > >> They are bitstypes so if you have a vectoe of them they will be stored >> "inline" in the vector. > > >
Re: [julia-users] Adding tuples
Awesome, I didn't realise this. I will definitely give them a try (and possibly eventually report back). It very likely makes more sense for our application for us to use these than an immutable tuple. Since they are mutable (I assume), we can pass them as an argument to a function to be written to (as output). Of course I realise there are many applications where the immutable tuples are better. Bill. On 12 August 2016 at 12:12, Kristoffer Carlssonwrote: > They are bitstypes so if you have a vectoe of them they will be stored > "inline" in the vector.
Re: [julia-users] Adding tuples
They are bitstypes so if you have a vectoe of them they will be stored "inline" in the vector.
Re: [julia-users] Adding tuples
We will have many of them, i.e. billions. Are FixedSizedArrays or StaticArrays individually allocated, e.g. if we have an array of them? Or would a large array of them be allocated once? Bill. On 12 August 2016 at 07:48, Andy Ferriswrote: > Bill, you might also consider FixedSizeArrays or StaticArrays, if your > data is all of the same type and `N` is a compile-time constant. I would be > curious how they benchmark against `ntuple(f, Val{N})`. >
Re: [julia-users] Adding tuples
Bill, you might also consider FixedSizeArrays or StaticArrays, if your data is all of the same type and `N` is a compile-time constant. I would be curious how they benchmark against `ntuple(f, Val{N})`.
Re: [julia-users] Adding tuples
Yes, from my experience tuples are commonly used when N is quite small and in the context of "adding tuples" it is likely that you want to do significant work with the resulting tuple and want the creation of it to be type stable. But as always, just benchmark it.
Re: [julia-users] Adding tuples
I guess this also depends on whether the benchmark (and the real scenario) involves doing this many times for the same N, or many times for different N. With the same N, it's probably going to be faster with Val{N}, but with many different N, using Val{N} is just going to make you pay the JIT fee for every new N instead of re-using an already compiled (but slightly less optimized) function. // T On Wednesday, August 10, 2016 at 10:06:18 PM UTC+2, Kristoffer Carlsson wrote: > > The Val{N} version will makes the compiler specialize the tuple creation > for that specific value of N. It should be significantly faster for small > lengths of the tuple and the return value should also be inferrable. > > On Wednesday, August 10, 2016 at 8:59:45 PM UTC+2, Jeffrey Sarnoff wrote: >> >> almost certainly -- I use BenchmarkTools for this sort of timing, and can >> recommend it. >> >> On Wednesday, August 10, 2016 at 2:56:17 PM UTC-4, Bill Hart wrote: >>> >>> For me, the version using CartesianIndex is exactly the same speed as >>> the syntax with the Val, which in turn is faster than without Val. >>> >>> It probably depends a lot on the application and what the compiler can >>> handle. >>> >>> Bill. >>> >>> On 10 August 2016 at 20:45, Jeffrey Sarnoff>>> wrote: >>> relative to the same thing without the Val On Wednesday, August 10, 2016 at 2:45:06 PM UTC-4, Jeffrey Sarnoff wrote: > > that slows it down by a factor of 5 > > On Wednesday, August 10, 2016 at 2:37:25 PM UTC-4, Bill Hart wrote: >> >> How about compared with: >> >> ntuple(i -> a[i] + b[i], Val{N}) >> >> >> On 10 August 2016 at 20:32, Jeffrey Sarnoff >> wrote: >> >>> Bill, >>> >>> Following Eric's note, I tried (with a,b equi-length tuples) >>> function addTuples(a,b) >>> ca = CartesianIndex(a) >>> cb = CartesianIndex(b) >>> return (ca+cb).I >>> end >>> >>> >>> for me, with 100 values it ran ~60% faster, and with 1000 values >>> much much faster than >>> ntuple(i -> a[i] + b[i], N) >>> >>> >>> >>> On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 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...@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 >>
Re: [julia-users] Adding tuples
The Val{N} version will makes the compiler specialize the tuple creation for that specific value of N. It should be significantly faster for small lengths of the tuple and the return value should also be inferrable. On Wednesday, August 10, 2016 at 8:59:45 PM UTC+2, Jeffrey Sarnoff wrote: > > almost certainly -- I use BenchmarkTools for this sort of timing, and can > recommend it. > > On Wednesday, August 10, 2016 at 2:56:17 PM UTC-4, Bill Hart wrote: >> >> For me, the version using CartesianIndex is exactly the same speed as the >> syntax with the Val, which in turn is faster than without Val. >> >> It probably depends a lot on the application and what the compiler can >> handle. >> >> Bill. >> >> On 10 August 2016 at 20:45, Jeffrey Sarnoffwrote: >> >>> relative to the same thing without the Val >>> >>> >>> On Wednesday, August 10, 2016 at 2:45:06 PM UTC-4, Jeffrey Sarnoff wrote: that slows it down by a factor of 5 On Wednesday, August 10, 2016 at 2:37:25 PM UTC-4, Bill Hart wrote: > > How about compared with: > > ntuple(i -> a[i] + b[i], Val{N}) > > > On 10 August 2016 at 20:32, Jeffrey Sarnoff > wrote: > >> Bill, >> >> Following Eric's note, I tried (with a,b equi-length tuples) >> function addTuples(a,b) >> ca = CartesianIndex(a) >> cb = CartesianIndex(b) >> return (ca+cb).I >> end >> >> >> for me, with 100 values it ran ~60% faster, and with 1000 values much >> much faster than >> ntuple(i -> a[i] + b[i], N) >> >> >> >> On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 >>> 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...@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 http://www.perimeterinstitute.ca/personal/eschnetter/ >>> >>> > >>
Re: [julia-users] Adding tuples
For me, the version using CartesianIndex is exactly the same speed as the syntax with the Val, which in turn is faster than without Val. It probably depends a lot on the application and what the compiler can handle. Bill. On 10 August 2016 at 20:45, Jeffrey Sarnoffwrote: > relative to the same thing without the Val > > > On Wednesday, August 10, 2016 at 2:45:06 PM UTC-4, Jeffrey Sarnoff wrote: >> >> that slows it down by a factor of 5 >> >> On Wednesday, August 10, 2016 at 2:37:25 PM UTC-4, Bill Hart wrote: >>> >>> How about compared with: >>> >>> ntuple(i -> a[i] + b[i], Val{N}) >>> >>> >>> On 10 August 2016 at 20:32, Jeffrey Sarnoff >>> wrote: >>> Bill, Following Eric's note, I tried (with a,b equi-length tuples) function addTuples(a,b) ca = CartesianIndex(a) cb = CartesianIndex(b) return (ca+cb).I end for me, with 100 values it ran ~60% faster, and with 1000 values much much faster than ntuple(i -> a[i] + b[i], N) On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 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...@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 http://www.perimeterinstitute. >> ca/personal/eschnetter/ >> > > >>>
Re: [julia-users] Adding tuples
almost certainly -- I use BenchmarkTools for this sort of timing, and can recommend it. On Wednesday, August 10, 2016 at 2:56:17 PM UTC-4, Bill Hart wrote: > > For me, the version using CartesianIndex is exactly the same speed as the > syntax with the Val, which in turn is faster than without Val. > > It probably depends a lot on the application and what the compiler can > handle. > > Bill. > > On 10 August 2016 at 20:45, Jeffrey Sarnoff> wrote: > >> relative to the same thing without the Val >> >> >> On Wednesday, August 10, 2016 at 2:45:06 PM UTC-4, Jeffrey Sarnoff wrote: >>> >>> that slows it down by a factor of 5 >>> >>> On Wednesday, August 10, 2016 at 2:37:25 PM UTC-4, Bill Hart wrote: How about compared with: ntuple(i -> a[i] + b[i], Val{N}) On 10 August 2016 at 20:32, Jeffrey Sarnoff wrote: > Bill, > > Following Eric's note, I tried (with a,b equi-length tuples) > function addTuples(a,b) > ca = CartesianIndex(a) > cb = CartesianIndex(b) > return (ca+cb).I > end > > > for me, with 100 values it ran ~60% faster, and with 1000 values much > much faster than > ntuple(i -> a[i] + b[i], N) > > > > On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 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...@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 >>> http://www.perimeterinstitute.ca/personal/eschnetter/ >>> >> >> >
Re: [julia-users] Adding tuples
relative to the same thing without the Val On Wednesday, August 10, 2016 at 2:45:06 PM UTC-4, Jeffrey Sarnoff wrote: > > that slows it down by a factor of 5 > > On Wednesday, August 10, 2016 at 2:37:25 PM UTC-4, Bill Hart wrote: >> >> How about compared with: >> >> ntuple(i -> a[i] + b[i], Val{N}) >> >> >> On 10 August 2016 at 20:32, Jeffrey Sarnoffwrote: >> >>> Bill, >>> >>> Following Eric's note, I tried (with a,b equi-length tuples) >>> function addTuples(a,b) >>> ca = CartesianIndex(a) >>> cb = CartesianIndex(b) >>> return (ca+cb).I >>> end >>> >>> >>> for me, with 100 values it ran ~60% faster, and with 1000 values much >>> much faster than >>> ntuple(i -> a[i] + b[i], N) >>> >>> >>> >>> On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 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...@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 > http://www.perimeterinstitute.ca/personal/eschnetter/ > >>
Re: [julia-users] Adding tuples
that slows it down by a factor of 5 On Wednesday, August 10, 2016 at 2:37:25 PM UTC-4, Bill Hart wrote: > > How about compared with: > > ntuple(i -> a[i] + b[i], Val{N}) > > > On 10 August 2016 at 20:32, Jeffrey Sarnoff> wrote: > >> Bill, >> >> Following Eric's note, I tried (with a,b equi-length tuples) >> function addTuples(a,b) >> ca = CartesianIndex(a) >> cb = CartesianIndex(b) >> return (ca+cb).I >> end >> >> >> for me, with 100 values it ran ~60% faster, and with 1000 values much >> much faster than >> ntuple(i -> a[i] + b[i], N) >> >> >> >> On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 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...@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 http://www.perimeterinstitute.ca/personal/eschnetter/ >>> >>> >
Re: [julia-users] Adding tuples
How about compared with: ntuple(i -> a[i] + b[i], Val{N}) On 10 August 2016 at 20:32, Jeffrey Sarnoffwrote: > Bill, > > Following Eric's note, I tried (with a,b equi-length tuples) > function addTuples(a,b) > ca = CartesianIndex(a) > cb = CartesianIndex(b) > return (ca+cb).I > end > > > for me, with 100 values it ran ~60% faster, and with 1000 values much much > faster than > ntuple(i -> a[i] + b[i], N) > > > > On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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 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...@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 http://www.perimeterinstitute. >>> ca/personal/eschnetter/ >>> >> >>
Re: [julia-users] Adding tuples
Bill, Following Eric's note, I tried (with a,b equi-length tuples) function addTuples(a,b) ca = CartesianIndex(a) cb = CartesianIndex(b) return (ca+cb).I end for me, with 100 values it ran ~60% faster, and with 1000 values much much faster than ntuple(i -> a[i] + b[i], N) On Wednesday, August 10, 2016 at 11:06:46 AM UTC-4, Bill Hart 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> 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...@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 >> http://www.perimeterinstitute.ca/personal/eschnetter/ >> > >
Re: [julia-users] Adding tuples
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 Gowdawrote: > > 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 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 http://www.perimeterinstitute. >>> ca/personal/eschnetter/ >>> >> >> >
Re: [julia-users] Adding tuples
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 Schnetterwrote: > >> 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 http://www.perimeterinstitute. >> ca/personal/eschnetter/ >> > >
Re: [julia-users] Adding tuples
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 Schnetterwrote: > 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 http://www.perimeterinstitute. > ca/personal/eschnetter/ >
Re: [julia-users] Adding tuples
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 Schnetterhttp://www.perimeterinstitute.ca/personal/eschnetter/