I see, thank you!

   (10) 6!:2 '(+)    i.10000000'
0.0286243
   (10) 6!:2 '(+&:+) i.10000000'     NB. process whole array
0.0273438
   (10) 6!:2 '(+@:+) i.10000000'
0.0290984
   (10) 6!:2 '([:++) i.10000000'
0.0281622

   (10) 6!:2 '+ + i.10000000'     NB. even this is slower
0.039037

  (10) 6!:2 '(+&+)  i.10000000'     NB. process item by item
1.06261
   (10) 6!:2 '(+@+)  i.10000000'
1.05878

On Thu, Jun 23, 2016 at 4:04 AM, Ric Sherlock <[email protected]> wrote:

> This isn't to do with forks vs trains per se. It is about J working better
> on (big) chunks rather than small ones. Using & or @ rather than &: or @:
> causes the verb to the left to operate on chunks that are a size determined
> by the rank of the verb to the right. Using @: or &: causes the verb to the
> right to finish processing and provide the entire array to the verb on the
> left.
>
> ([: *: >:) is equivalent to *:@:>:
> In this case the answer is the same as for *:@>: but the processing path is
> different.
>
> Both >: and *: are rank 0
>    >: b. 0
>
> 0 0 0
>
>    *: b. 0
>
> 0 0 0
>
>
> So *:@>: will process each atom of the argument separately whereas *:@:>:
> will finish incrementing all the atoms in the argument and then give the
> entire result to square (*:) to process. This might help visualise what is
> going on:
>
>
> <@:*:@>:  0 1 2 3 4 5
>
> +-+-+-+--+--+
>
> |1|4|9|16|25|
>
> +-+-+-+--+--+
>
> <@:*:@:>:  0 1 2 3 4 5
>
> +-----------+
>
> |1 4 9 16 25|
>
> +-----------+
>
>
> Looking at the timing differences in sentences below you can see that they
> key is that *: is operating on the entire array.
>
> 6!:2 '(+/@:(*:&>:&i.))"0 (i.9999)'
>
> 13.55
>
> 6!:2 '(+/@:(*:&:>:&:i.))"0 (i.9999)'
>
> 0.162699
>
> 6!:2 '(+/@:(*:@:>:@:i.))"0 (i.9999)'
>
> 0.169901
>
> 6!:2 '(+/@:(*:@>:@i.))"0 (i.9999)'
>
> 13.4185
>
> 6!:2 '(+/@:(*:@:>:@i.))"0 (i.9999)'
>
> 0.156401
>
> 6!:2 '(+/@:(*:@>:@:i.))"0 (i.9999)'
>
> 13.49
>
>
> Note that there appears to be no performance benefit between >:@i. and
> >:@:i. because the monadic rank of i. is 1
>    i. b. 0
>
> 1 _ _
>
>
> The rank of the argument given to i. is already 1 or less, so >: is being
> given the whole result from i. already.
>
> Hope that helps
>
> On Thu, Jun 23, 2016 at 12:10 PM, Moon S <[email protected]> wrote:
>
> > I was searching integer solutions (k,m) for
> >    1^2 + 2^2 + ... + k^2 = m^2
> > and I found that one expression runs much faster than the other:
> >
> >    (#~(0=1|[:%:+/@:([:*:1+i.))"0) 2+i.9999
> > 24
> >    (#~(0=1|[:%:+/@:(*:&>:&i.))"0) 2+i.9999
> > 24
> >
> > The first one is ~100 times faster, and moreover, the expression with
> '+/'
> > is faster, then without it!
> >
> >    (3) 6!:2 '(+/@:([:*:1+i.))"0 (i.9999)'         NB. with +/ and fork
> > 0.143744
> >    (3) 6!:2 '(+/@:(*:&>:&i.))"0 (i.9999)'        NB. with +/ and train
> > 13.4614
> >
> >    (3) 6!:2 '([:*:1+i.)"0 (i.9999)'      NB. without +/
> > 0.608895
> >    (3) 6!:2 '(*:&>:&i.)"0 (i.9999)'
> > 14.0192
> >
> > As for '+/' I think the explanation is that no additional arrays are
> > created, the sums are just computed on the fly.
> > But the question remains, why the (equivalent) fork is so much faster
> than
> > the train?
> >
> > Hm, changing the long train to a shorter one with a fork helps:
> >    (3) 6!:2 '(*:&(1+i.))"0 (i.9999)'
> > 0.62027
> > So, what's the rule?
> >
> > ---
> > Georgiy Pruss
> > ----------------------------------------------------------------------
> > For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to