[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Slowness when using lambda expressions
From: |
Xiao-Yong Jin |
Subject: |
Re: Slowness when using lambda expressions |
Date: |
Mon, 30 Mar 2020 09:45:23 -0500 |
Compare with Dyalog,
]runtime +/⍳1000000
* Benchmarking "+/⍳1000000"
(ms)
CPU (avg): 1
Elapsed: 1
]runtime {⍺+⍵}/⍳1000000
* Benchmarking "{⍺+⍵}/⍳1000000"
(ms)
CPU (avg): 270
Elapsed: 279
> On Mar 30, 2020, at 9:38 AM, Xiao-Yong Jin <address@hidden> wrote:
>
> For comparison, here is J,
>
> JVERSION
> Engine: j901/j64avx2/darwin
> Release-e: commercial/2020-01-29T12:41:32
> Library: 9.01.21
> Platform: Darwin 64
> Installer: J901 install
> InstallPath: /applications/j901
> Contact: www.jsoftware.com
> timex'+/i.1000000'
> 0.00184
> plus=:4 :'x+y'
> timex'plus/i.1000000'
> 0.151494
>
> 'timex' function returns seconds elapsed.
>
>> On Mar 30, 2020, at 7:35 AM, Blake McBride <address@hidden> wrote:
>>
>> This brings up an interesting point. Truth is, the functional programming
>> model is extremely slow unless, as it often is, the function call is
>> optimized out.
>>
>> On Mon, Mar 30, 2020 at 6:51 AM Elias Mårtenson <address@hidden> wrote:
>> Thank you for the clarification. I can see that the problem isn't that the
>> lambda function is slow. It's the +/ variant that is really fast. :-)
>>
>> Of course, as you say, in real code you'd never write it the way I did. :-)
>>
>> Regards,
>> Elias
>>
>> On Mon, 30 Mar 2020 at 17:53, Dr. Jürgen Sauermann
>> <mail@jürgen-sauermann.de> wrote:
>> Hi Elias,
>>
>> in GNU APL (and I suppose also in other APLs) lambda expressions are not
>> macros (or inline functions) but fully-fledged defined functions.
>> That is,
>>
>> {⍺+⍵}/ ⍳1000000 is NOT equivalent to: +/ ⍳1000000
>>
>> Rather:
>>
>> ∇Z←A PLUS B
>> Z←A + B
>> ∇
>>
>> and then:
>>
>> {⍺+⍵}/ ⍳1000000 is equivalent to: FOO/⍳1000000
>>
>> The 12 seconds are mainly spent for one million calls
>> of FOO, each call passing two scalar arguments A and B
>> and returning a scalar Z. It also wraps every Cell (i.e. every
>> ravel item) of A, B, and Z into a scalar value A, B, and Z.
>> Ravel cells are rather light-weight while values are more heavy
>> (each scalar value has, for example, its own shape vector).
>> And finally: each call of FOO pushes and pops an )SI entry and
>> a value stack entry for each A, B, and Z. These operations
>> are pretty fast but become noticeable if you do them very often.
>>
>> In your example one call of FOO takes 12 micro-seconds which
>> is, IMHO, not too bad.
>>
>> You could have avoided this overhead by computing:
>>
>> {+/ ⍵} ⍳1000000 instead of: {⍺+⍵}/ ⍳1000000
>>
>> Best Regards,
>> Jürgen Sauermann
>>
>>
>> On 3/30/20 3:39 AM, Elias Mårtenson wrote:
>>> The following expression takes about 12 seconds to compute on my laptop:
>>>
>>> {⍺+⍵}/ ⍳1000000
>>>
>>> However, the equivalent expression without the lambda expression is
>>> immediate (i.e. thr prompt returns before I have time to notice that it
>>> even started calculating):
>>>
>>> +/ ⍳1000000
>>>
>>> What is causing the large difference in performance?
>>>
>>> Regards,
>>> Elias
>>
>