Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Fastest method to get distance between objects? - Gideros Forum

Fastest method to get distance between objects?

Apollo14Apollo14 Member
edited August 1 in Code snippets
Hi guys!
I've checked 3 methods of getting distance between two points.
Number of tests:	1000000
testDistance1	2.1159432063358
testDistance2	1.6703890134563
testDistance3	1.6123716717074
I have 2 questions:
1) Why does Profiler print results when 'maxIterations' is set to 10.000, but doesn't print anything when 'maxIterations=1.000.000'?
2) How to improve 3rd function? Can we put math.sqrt in Macro function? I don't get how to make it work:
MATHSQRT @ (|
	local enteredNum=...
	return math.sqrt(enteredNum[1])
|)
(p. s. I don't know, maybe 'bump' can measure distance better, but I don't feel I really need it in my current projects, and I'm trying to understand how macro functions work.

Thanks!

Test project's code:
maxIterations@10000
local randomSeed,random=Core.randomSeed,Core.random
randomSeed(1,1)
 
function testDistance1()
	local distanceNum=0; randomSeed(1,1)
 
	for i=1,maxIterations do
		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
		local dx, dy = math.abs(x1 - x2), math.abs(y1 - y2)
		distanceNum = math.sqrt(dx*dx + dy*dy)
	end
end
 
function testDistance2()
	local distanceNum=0; randomSeed(1,1)
 
	for i=1,maxIterations do
		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
		distanceNum = math.sqrt((x1 - x2)^2 + (y1 - y2)^2)
	end
end
 
function testDistance3()
	local distanceNum=0; randomSeed(1,1)
 
	for i=1,maxIterations do
		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
		local xfactor = x2-x1 ; local yfactor = y2-y1
		distanceNum = math.sqrt((xfactor*xfactor) + (yfactor*yfactor))
	end
end
 
--4th function doesn't work:
MATHSQRT @ (|
	local enteredNum=...
	return math.sqrt(enteredNum[1])
|)
function testDistance4()
	local distanceNum=0; randomSeed(1,1)
 
	for i=1,maxIterations do
		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
		local xfactor = x2-x1 ; local yfactor = y2-y1
		distanceNum = MATHSQRT((xfactor*xfactor) + (yfactor*yfactor))
	end
end
 
--Let's test first 3 functions:
Core.profilerReset()
Core.profilerStart()
for loop=1,10 do
	testDistance1()
	testDistance2()
	testDistance3()
	--testDistance4()
end
Core.profilerStop()
 
-- print the results of the profiler
result=Core.profilerReport()
print("Number of tests:",maxIterations*10)
 
for k,v in pairs(result) do
	local found=false
 
	for k2,v2 in pairs(v) do
		if found and k2=="time" then print(v1,v2) end
		if k2=="name" and string.sub(v2,1,4)=="test" then v1=v2 found=true end
	end
end
> Newcomers roadmap: from where to start learning Gideros
"What one programmer can do in one month, two programmers can do in two months." - Fred Brooks

Comments

  • SinisterSoftSinisterSoft Maintainer
    1: You will have to wait 100 times longer for 1,000,000 vs 10,000
    2: I'm not sure what you mean - a macro won't make it any faster - it basically replaces the text with the text in the macro as it gets converted to bytecode. The bytecode is then executed.

    In some cases the macro will be faster than using a variable - but only slightly. eg:

    variable:
    x=5
    a=x*2 -- this can't be optimised by the bytecode compiler
    print(a)
    macro 'constant':
    x@5
    a=x*2  -- this is translated to 5*2, it's then optimised to 10, so it gets compiled as a=10
    print(a)

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    edited August 1
    if you only want to measure if one thing is nearer than another then don't bother with the end sqrt, just use the (dx*dx)+(dy*dy). If you need the actual distance then you need the sqrt. As sqrt takes ages anyhow I didn't add it as a new operator as the time needed to call the library is minimal in comparison (it could also be that maybe the math.sqrt uses some hardware sqrt machine code mnemonic in some cases).

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    As regards distance (before sqrt), normally I do:
    dx2=dx*dx
    dy2=dy*dy
    da=dx2+dy2
    But if you don't need dx or dy in the future then this may be faster:
    dx*=dx
    dy*=dy
    da=dx+dy
    But I don't know if either is faster than this on it's own - I've not tested.
    da=(dx*dx)+(dy*dy)

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • Apollo14Apollo14 Member
    edited August 4
    uh, for some reason with mutation operators function works slower:
    function testDistance3() --without mutation operators (faster)
    	local distanceNum=0; randomSeed(1,1)
     
    	for i=1,maxIterations do
    		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
    		local xfactor = x2-x1 ; local yfactor = y2-y1
    		distanceNum = math.sqrt((xfactor*xfactor) + (yfactor*yfactor))
    	end
    end
     
    function testDistance4() --with mutation operators (slower)
    	local distanceNum=0; randomSeed(1,1)
     
    	for i=1,maxIterations do
    		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
    		x2-=x1; y2-=y1
    		x2*=x2; y2*=y2
    		x2+=y2
    		distanceNum = math.sqrt(x2)
    	end
    end
    Number of tests:	1000000
    testDistance3	1.6350071765395
    testDistance4	1.9041770702311
    these variations with mutation operators are also slower:
    function testDistance4()
    	local distanceNum=0; randomSeed(1,1)
     
    	for i=1,maxIterations do
    		local x1,x2,y1,y2=random(0,320),random(0,320),random(0,480),random(0,480)
    		x2-=x1; y2-=y1
    		distanceNum = math.sqrt(x2*x2+y2*y2)
    	end
    end
     
    function testDistance4()
    	local distanceNum=0; randomSeed(1,1)
     
    	for i=1,maxIterations do
    		local x2,y2=random(0,320),random(0,480)
    		x2-=random(0,320); y2-=random(0,480)
    		distanceNum = math.sqrt(x2*x2+y2*y2)
    	end
    end
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • SinisterSoftSinisterSoft Maintainer
    That's odd - it should be faster as it doesn't need to search twice for the variable.
  • SinisterSoftSinisterSoft Maintainer
    I just did this...

    Number of tests: 10000000
    test1 24.56468319438
    test2 22.882652866686

    test 2 being the mutation operators. Maybe something happened on the computer that slowed it down in your case for the 2nd test?
  • Apollo14Apollo14 Member
    edited August 4
    This is interesting.
    I was testing these functions in a temporary draft project with lots of dirty code commented out. Mutation operators are always slower there, something is slowing them down.
    Does commented out code affect perfomance?

    But when I created blank V2 project without commented out stuff, mutation operators work faster as we normally expect.

    I've attached 2 projects here:
    zip
    zip
    benchmarks_V1_V2.zip
    257K
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
  • SinisterSoftSinisterSoft Maintainer
    Comments should be ignored by the bytecode conversion, not sure though.
  • SinisterSoftSinisterSoft Maintainer
    I tested your two project - I get the same as you - very odd.

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
Sign In or Register to comment.