Timing question

Started by Fritz, October 04, 2009, 09:18:14 AM

Previous topic - Next topic

Fritz

I have a simple function to short my code, this function just adds args to the big string (that string "cuerpo" is a body of html file).


(define (meter)
  (dolist (x (args))
    (push (string x) cuerpo -1)))


But I have noticed, that using this function instead of


(push "<td>" cuerpo -1)

slows script from 50 ms to about 11'000 ms (I have a table with 2k rows). Then I have tried to simple "meter" function:


(define (meter-2 arg-1)
  (push arg-1 cuerpo -1))


But it is as slow as first one. May be, I should try a macro or something?

cormullion

#1
Does this make things faster?


(define (meter )
 (dolist (x (args))
    (push (string x) cuerpo -1)
    0))


there was a thread about this some time ago but I can't find it...

Fritz

#2
Yep, that works. Script slows from 31 ms to 61 ms, but that is ok. I see my error now.

Jeff

#3
Remember that function arguments are passed by value - that is, they are copied on every call. You can avoid this by assigning a large value to a symbol and passing the symbol itself to the function instead.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Fritz

#4
Quote from: "Jeff"...You can avoid this by assigning a large value to a symbol...


But how?


(define (triple n)
  (+ (expand n) 1))

(set 'x 3)
(triple 'x)

Jeff

#5
(define (triple n)
  (expand (* 3 n) n))


Or use 'eval'.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Fritz

#6
Quote from: "Jeff"(define (triple n)
  (expand (* 3 n) n))


Have tried:



(set 'x 3)



(triple 'x)

(triple x)

(triple "x")

(triple ''x)



Only this combination works:


(define (triple n)
  (* 3 (eval n)))

(triple 'x)

cormullion

#7
perhaps have a look at section 16 of the reference manual, Passing data by reference...



Your iterations were closer than you think:



(define (triple n)

  (* 3 (eval n)))

(set 'x 3)



(triple 'x)

  ; passes symbol x without evaluating it - this should work when you eval x, if it's a number

(triple x)

   ; evaluates x, then passes the 3 value - this should also work, since, inside triple, (eval 3) returns 3

(triple "x")

   ; strings evaluate to themselves, not a number, so the multiply will fail

(triple ''x)

   ; passes 'x to function; (eval n) returns x, but x is not a number (needs another eval)...



But - to return to an earlier reply - I still don't remember why that 0 in the dolist loop increased the speed. Something to do with references returned by push ... ?

Fritz

#8
Quote from: "cormullion"why that 0 in the dolist loop increased the speed.


As I can see, (push token big-string) operator returns big-string. In my script this string (at the end) is about 300k long, and I call push function about 20k times.



So, function returns (20k * 300k) / 2  = 3'000'000'000 extra characters, and it lags my script by about 0.5 seconds.



But if I put "0" at the end, I receieve from function as a result only 20k zeroes.

cormullion

#9
Yes, that was my thinking too. But everyone says that push now returns a reference, so I'm inclined to think that it shouldn't be any slower...

Lutz

#10
Quotepush now returns a reference


yes, but the 'define'd function does not, it returns a copy.

cormullion

#11
Ah so I could also have written:


(define (meter)
 (dolist (x (args))
    (push (string x) cuerpo -1))
0)


ie just the function returning 0, rather than the dolist body...