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" <mike.pech...@gmail.com>:
>>
>>> hi,
>>>
>>> On Fri, Feb 10, 2017 at 3:07 PM, Christopher Howard <
>>> christopher.how...@qlfiles.net> 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)
>>
>>
>

Reply via email to