Page 1 of 1
Timing question
Posted: Sun Oct 04, 2009 4:18 pm
by 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).
Code: Select all
(define (meter)
(dolist (x (args))
(push (string x) cuerpo -1)))
But I have noticed, that using this function instead of
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:
Code: Select all
(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?
Posted: Sun Oct 04, 2009 6:08 pm
by cormullion
Does this make things faster?
Code: Select all
(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...
Posted: Sun Oct 04, 2009 7:49 pm
by Fritz
Yep, that works. Script slows from 31 ms to 61 ms, but that is ok. I see my error now.
Posted: Mon Oct 05, 2009 12:55 pm
by Jeff
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.
Posted: Mon Oct 05, 2009 1:39 pm
by Fritz
Jeff wrote:…You can avoid this by assigning a large value to a symbol…
But how?
Code: Select all
(define (triple n)
(+ (expand n) 1))
(set 'x 3)
(triple 'x)
Posted: Mon Oct 05, 2009 1:41 pm
by Jeff
Code: Select all
(define (triple n)
(expand (* 3 n) n))
Or use 'eval'.
Posted: Mon Oct 05, 2009 1:54 pm
by Fritz
Jeff wrote:Code: Select all
(define (triple n)
(expand (* 3 n) n))
Have tried:
(set 'x 3)
(triple 'x)
(triple x)
(triple "x")
(triple ''x)
Only this combination works:
Code: Select all
(define (triple n)
(* 3 (eval n)))
(triple 'x)
Posted: Mon Oct 05, 2009 5:17 pm
by cormullion
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 ... ?
Posted: Mon Oct 05, 2009 5:54 pm
by Fritz
cormullion wrote: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.
Posted: Mon Oct 05, 2009 6:42 pm
by cormullion
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...
Posted: Mon Oct 05, 2009 7:09 pm
by Lutz
push now returns a reference
yes, but the 'define'd function does not, it returns a copy.
Posted: Mon Oct 05, 2009 7:20 pm
by cormullion
Ah so I could also have written:
Code: Select all
(define (meter)
(dolist (x (args))
(push (string x) cuerpo -1))
0)
ie just the function returning 0, rather than the dolist body...