Page 1 of 1
Alternative to "do"
Posted: Sat Nov 09, 2013 8:05 pm
by dhurtt
I am looking for an alternative to using the "do" command. What I have works, but I just want to see if there is a more efficient way of doing my task that I am not aware of, as I understand that "do" has to compile on the fly, so may be slower. What I am doing is something like this:
Code: Select all
function a x, y
# return something
end a
function b x, y
# return something
end b
function c x, y
# return something
end c
function getFunction n, m
if someCondition then
return "a"
else if someOtherCondition then
return "b"
else
return "c"
end if
end getFunction
on mouseup
# some code to get n, m, x, and y ...
put getFunction(n, m) into myFunction
do "put" && myFunction & "(x, y) into someVariable"
# do something with someVariable
end mouseup
I have noticed that I can call a variable and it will find the command of that name, but it does not seem to work with functions. Maybe I am doing something wrong syntactically? This works:
Code: Select all
command a
answer "a"
end a
command b
answer "b"
end b
command aorb
answer question "a or b?" with "a" or "b"
call it
end aorb
But this does not:
Code: Select all
function a x, y
return "x"
end a
function b x, y
return "y"
end b
command aorb
answer question "a or b?" with "a" or "b"
call it(1, 2)
answer it
end aorb
It complains that it cannot find the message handler. Walking through the debugger, "it" contains the proper value. So it seems that "call" cannot be used with functions, only commands?
Thanks in advance,
Dale
Re: Alternative to "do"
Posted: Sat Nov 09, 2013 11:09 pm
by dunbarx
Hi.
These things do get convoluted. For your last code thingie, does this help?
Code: Select all
function a x, y
return "x"
end a
function b x, y
return "y"
end b
on mouseUp
answer question "a or b?" with "a" or "b"
get "get" && it & "(1, 2)"
do it
answer it
end mouseUp
At least this is syntactically correct, but is a house of cards.
And just for fun:
Code: Select all
on mouseUp
answer question "a or b?" with "a" or "b"
answer "do get get" && it & "(1, 2)"
end mouseUp
Craig Newman
Re: Alternative to "do"
Posted: Sat Nov 09, 2013 11:34 pm
by FourthWorld
It may seem awfully pedestrian, but have you considered an "if" or "case" block?
Re: Alternative to "do"
Posted: Sun Nov 10, 2013 12:39 am
by dhurtt
FourthWorld wrote:It may seem awfully pedestrian, but have you considered an "if" or "case" block?
Yes I have. These are simplified examples, not the real code. My functions are called based on the result of mathematical calculations; they determine the next step to take. They are called from multiple points in the code, which is why they are pulled out into separate functions. Embedding the calculations used to determine which function to call in multiple handlers sprinkled throughout the code is very bad practice.
For example, I have used a command, "aorb", as the "calculation" of which function to call, "a" or "b". Imagine I do as you suggest and pull out the code inside "aorb" and proliferate it in four different spots. Now imagine that I need to change the number of functions that are called; I now have a function "c". Or I need to change the way in which the functions are called (maybe add a new parameter). You start to see how it gets ugly fast.
But I did post this on the beginner's forum, so thanks for asking. You never know when it would apply.
"do" seems like it is a cousin to Javascript's "eval", as both have to evaluate strings and come up with machine instructions on the fly, thus it is "expensive". I am simply trying to find out if there was another way, like with the "call" command, to call a function whose name is within a variable. I suspect that "get" also functions in the same way as "do" (i.e. is just as expensive) as it evaluates the string according to the API documentation. I now wonder whether "call" is doing the same?
Re: Alternative to "do"
Posted: Sun Nov 10, 2013 2:19 am
by FourthWorld
Well, I was only half-right: while case is faster than do in some scenarios, dispatch is fastest.
Of course the speed of case will depend on the number of cases, but given this script in a button:
Code: Select all
on mouseUp
put "foo" into tCmd
put 100000 into N
--
-- Test 1: dispatch
put the millisecs into t
repeat N
dispatch tCmd
end repeat
put the millisecs - t into t1
--
-- Test 2: do
put the millisecs into t
repeat N
do tCmd
end repeat
put the millisecs - t into t2
--
-- Test 3: case
put "foo"& 10 into tCmd
put the millisecs into t
repeat N
switch tCmd
case "foo1"
foo1
break
case "foo2"
foo2
break
case "foo3"
foo3
break
case "foo4"
foo4
break
case "foo5"
foo5
break
case "foo6"
foo6
break
case "foo7"
foo7
break
case "foo8"
foo8
break
case "foo9"
foo9
break
case "foo10"
foo10
break
end switch
end repeat
put the millisecs - t into t3
--
-- Test 4: call
put the millisecs into t
repeat N
call tCmd
end repeat
put the millisecs - t into t4
put "dispatch: "& t1 &" do: "& t2 &" case: "& t3 &" call: "& t4
end mouseUp
And this script in the card:
Code: Select all
on foo
get 1+1
end foo
on foo1
get 1+1
end foo1
on foo2
get 1+1
end foo2
on foo3
get 1+1
end foo3
on foo4
get 1+1
end foo4
on foo5
get 1+1
end foo5
on foo6
get 1+1
end foo6
on foo7
get 1+1
end foo7
on foo8
get 1+1
end foo8
on foo9
get 1+1
end foo9
on foo10
get 1+1
end foo10
Here are the results:
dispatch: 277 do: 438 case: 336 call: 389
While confirming the boost with case was mildly interesting, the benefits of dispatch are so overwhelming that it doesn't matter, and dispatch is much simpler to use than writing a tedious case block.
If you do a lot of benchmarking in LiveCode there may be some things here of interest:
Benchmarking Performance in LiveCode
http://livecodejournal.com/tutorials/be ... vtalk.html
Re: Alternative to "do"
Posted: Sun Nov 10, 2013 3:12 am
by dhurtt
"dispatch" appears to be the command I was looking for. Thanks!