If it even matters, the overhead of recurse is slowest here.
So impressive that picolisp can iterate/recurse over a 10M element list in
these times.
(VirtualBox VM, 4GB, 1Core, with 64bit Debian).
.. and 'make' is a lot more useful that I first realized.
/Lindsay
# Iterative
(de sumi (L)
(let (Sum (car L))
(while (setq L (cdr L))
(setq Sum (+ Sum (car L))) ) ) )
# Recurse
(de sumr (N)
(cond
((not N) 0)
(T (+ (car N) (sumr (cdr N)))) ) )
# This may take a moment...
: (setq bigly (range 1 10000000) D NIL) -> NIL
: (bench (apply '+ bigly)) 0.097 sec -> 50000005000000
: (bench (sum '+ bigly)) 0.139 sec -> 50000005000000
: (bench (sumi bigly)) 0.275 sec -> 50000005000000
: (bench (sumr bigly)) 0.639 sec -> 50000005000000
: (setq bigly (need 10000000 1) D NIL) -> NIL
: (bench (apply '+ bigly)) 0.099 sec -> 10000000
: (bench (sum '+ bigly)) 0.139 sec -> 10000000
: (bench (sumi bigly)) 0.272 sec -> 10000000
: (bench (sumr bigly)) 0.643 sec -> 10000000
: (bench (setq bigly (make (for X 10000000 (link (+ (- 10000000 X) 1)))))
(length bigly)) 0.437 sec -> 10000000
: (bench (sumr bigly)) 0.630 sec -> 50000005000000
: (bench (sumi bigly)) 0.279 sec -> 50000005000000
Am 10.02.2017 15:28 schrieb "Mike Pechkin" <[email protected]>:
>>
>>> hi,
>>>
>>> On Fri, Feb 10, 2017 at 3:07 PM, Christopher Howard <
>>> [email protected]> wrote:
>>>
>>> > Hi list. When I try to do
>>> >
>>> > (apply '+ (range 1 1000000)
>>> >
>>>
>>>
>>> List of millions of items is not a problem.
>>> Problem how you use it.
>>> (apply) is not for free, It *creates* a function call with a million of
>>> arguments.
>>> Stack size make sense.
>>>
>>>
>>> > I get segfault. I thought maybe this was some kind of internal
>>> > limitation of the apply function, so I defined a foldl:
>>> >
>>> > (de foldl (Fn Acc Lst)
>>> > (if (== () Lst) Acc
>>> > (let Acc2 (Fn Acc (car Lst))
>>> > (foldl Fn Acc2 (cdr Lst)) ) ) )
>>> >
>>> > : (foldl '+ 0 (range 1 1000))
>>> > (foldl '+ 0 (range 1 1000))
>>> > -> 500500
>>> > : (foldl '+ 0 (range 1 1000000))
>>> > (foldl '+ 0 (range 1 1000000))
>>> >
>>> >
>>>
>>> Stack size makes sense too.
>>> I like recursions this way:
>>>
>>> (de rec1 (F A L)
>>> (if L
>>> (rec1 F (inc 'A (++ L)) L)
>>> A ) )
>>>
>>> recursion with hidden accumulator from outer call and car-cdr:
>>> (de rec2 (F L A)
>>> (default A 0)
>>> (if L
>>> (rec2 F (cdr L) (inc 'A (car L)))
>>> A ) )
>>> The call will be: (rec2 '+ (range 1 1000000)))
>>>
>>>
>>> As recursion just loop you can implement it without big stack too:
>>> (de sum1 (L)
>>> (let N 0
>>> (for I L
>>> (inc 'N I) ) ) )
>>>
>>> even without list creation:
>>> (de sum2 (X)
>>> (let N 0
>>> (for I X
>>> (inc 'N I) ) ) )
>>>
>>>
>>> And finally, that's why (sum) was implemented:
>>> (sum prog (range 1 1000000)))
>>>
>>>
>>> Bonus: for practice write recursion function to sum numbers without
>>> (range)
>>
>>
>