(ymg_in_range_1 0 10.5 1) => (0 1 2 3 4 5 6 7 8 9 10)
(ymg_in_range_1 0 3 2) => (0 2)
(ymg_in_range_2 0 10.5 1) => (0 1 2 3 4 5 6 7 8 9)
(ymg_in_range_2 0 3 2) => (0)
(cab_in_range_1 0 10 1) => (0 1 2 3 4 5 6 7 8 9 10)
In the Python implementation is 'start' always smaller than 'end'?
Have you seen the work of Sergey Bochkanov ALGLIB Project --- for the LMA - give it a read/try:
recursion way
Quoterecursion way
Best one!!! by a tall margin.
ymg
(EE_range 0 -10 -1) => nil
@ ElpanovEvgeniy:
Your function is nice and short but:
Code: [Select]
(EE_range 0 -10 -1) => nil
@ ElpanovEvgeniy:
Your function is nice and short but:Code: [Select](EE_range 0 -10 -1) => nil
But we still haven't addressed if there is any merit to such construct as
(foreach i (in_range 0 10 1) ....
(foreach i (in_range 0 10 1) [I do not understand what needs to be here] ....
(foreach i (in_range 0 10 1)
(setq tot (+ tot i))
)
Here is a stupid one:Code: [Select](foreach i (in_range 0 10 1)
(setq tot (+ tot i))
)
In other word we do not need to increment the index to the loop.
The python boys use it at every sauce.
ymg
Code - Auto/Visual Lisp: [Select]
So what, little testings where I was wrong...
_$ (c:test)
Recursive in_range(): 0.109 secs
_$ (c:test1)
Iterative inrange(): 0.109 secs
_$ (c:test2)
Traditionnal Index: 0.047 secs
_$
It should be almost like (c:test2)...
_$ (c:test4)
Foreach in_range(): 0.047 secs
Benchmarking .......... elapsed milliseconds / relative timing <5000 iterations>
(KGA_LIST_INDEXSEQMAKESTARTEND 0 100) ..... 125 / 4.62 <fastest>
(CAB_IN_RANGE 0 100 1) .................... 235 / 2.46
(EE_IN_RANGE 0 100 1) ..................... 578 / 1.00 <slowest>
@ ymg & ribarm
Benchmarking is not a 'real situation'. If you are trying to benchmark the range functions you should keep it inside the (repeat 5000 ...) loop.
;; By roy_043 ;
(defun in_ranger (start end / len ret step)
(setq step (if (< start end) -1 1))
(repeat (rem (setq len (fix (abs (- end start)))) 8)
(setq ret (cons (setq end (+ end step)) ret))
)
(repeat (/ len 8)
(setq ret
(vl-list*
(+ end (* 8 step))
(+ end (* 7 step))
(+ end (* 6 step))
(+ end (* 5 step))
(+ end (* 4 step))
(+ end (* 3 step))
(+ end (* 2 step))
(+ end step)
ret
)
)
(setq end (+ end (* 8 step)))
)
ret
)
(defun c:testr ()
(setq ti (car (_vl-times)))
(setq l (in_ranger 0 10)) ;; or (setq l (in_rangec 0 10 1))
(repeat 5000
(setq tot 0)
(foreach i l
(setq tot (+ tot i))
)
)
(princ (strcat "\nForeach in_ranger(): " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs"))
(princ)
)
(c:testr)
Foreach in_ranger(): 0.0470 secs
@roy: Just curious, why 8? Why not more (or less)?From my test file:
;;; 20111115
;;; Conclusions:
;;; The (repeat) loop with (setq) is very time consuming.
;;; Using serial (cons) is usually slower than using (vl-list*).
;;; Using (append) is of course bad for speed.
;;; (KGA_LIST_INDEXSEQMAKELENGTH_08) has an acceptable balance between speed gain and program length.
; Benchmarking .......... elapsed milliseconds / relative timing <1000 iterations>
; (KGA_LIST_INDEXSEQMAKELENGTH_32 1000) ...... 125 / 2.88 <fastest>
; (KGA_LIST_INDEXSEQMAKELENGTH_16 1000) ...... 140 / 2.57
; (KGA_LIST_INDEXSEQMAKELENGTH_08 1000) ...... 172 / 2.09
; (KGA_LIST_INDEXSEQMAKELENGTH_04 1000) ...... 234 / 1.54
; (KGA_LIST_INDEXSEQMAKELENGTH_01 1000) ...... 360 / 1.00 <slowest>
Very thorough roy :-):kewl: