Point out the inefficienes in my code

So basically, I’ve made this script that determines a point’s distance from a region of points.
See Example:

This is the main bit of the code the rest of the code is just pure mathematical solving (the functions being called)

while true do
	task.wait()
	for index, landPoint in	ipairs(LandPoints:GetChildren()) do
		landPoint.Color = Color3.new(1, 0, 0)
		if (ClosestPoint.Position-PointA.Position).Magnitude > (landPoint.Position-PointA.Position).Magnitude then
			ClosestPoint = landPoint
		end
	end
	
	local ClosePointNum = tonumber(string.split(ClosestPoint.Name,"t")[2])
	local LeftPoint
	local RightPoint
	
	if ClosePointNum == 1 then
		RightPoint = LandPoints:FindFirstChild("Point"..tostring(ClosePointNum+1))
		LeftPoint = LandPoints:FindFirstChild("Point"..tostring(#LandPoints:GetChildren()))
	elseif ClosePointNum == #LandPoints:GetChildren() then
		RightPoint = LandPoints:FindFirstChild("Point1")
		LeftPoint = LandPoints:FindFirstChild("Point"..tostring(ClosePointNum-1))
	else
		LeftPoint = LandPoints:FindFirstChild("Point"..tostring(ClosePointNum-1))
		RightPoint = LandPoints:FindFirstChild("Point"..tostring(ClosePointNum+1))
	end
	
	local PointDistance
	
	local RightPointTri = checkForRightAngle(SidesOfATriangle(ClosestPoint.Position, RightPoint.Position, PointA.Position))
	local LeftPointTri
	if RightPointTri then
		RightPoint.Color = Color3.new(0.458824, 1, 0.952941)
		local sideA, sideB, sideC = SidesOfATriangle(ClosestPoint.Position, RightPoint.Position, PointA.Position)
		PointDistance = calulateHeightOfTriangle(sideA, sideB, sideC)
	else
		local sideA, sideB, sideC = SidesOfATriangle(ClosestPoint.Position, LeftPoint.Position, PointA.Position)
		LeftPointTri = checkForRightAngle(sideA, sideB, sideC)
		if LeftPointTri then
			LeftPoint.Color = Color3.new(0.458824, 1, 0.952941)
			PointDistance = calulateHeightOfTriangle(sideA, sideB, sideC)
		end
	end
	
	if PointDistance == nil then
		PointDistance = (ClosestPoint.Position-PointA.Position).Magnitude
	end
	ClosestPoint.Color = Color3.new(0.129412, 1, 0.203922)
	
	print(math.round(PointDistance))
end
1 Like

First of all, use runservice instead of while loop. Second of all, when you have an infinite loop, your goal is to do as much of the computation outside of that loop. Whatever’s in that loop runs every tick, so it needs to be as minimal as possible.

I see you’re calling GetChildren multiple times, this is computation that can be done outside of the loop and stored in a local variable.

I see you’re doing concat & split operations, which you want to avoid doing every tick, as they can be slow. I think you should sort your children alphabetically (if not already) and then just use the closeNumPoint as an index in the already computed array and do math.clamp(index - 1, 1, #arr) same for index + 1 to get right and left points. Simple math on numbers and array accessing is much faster than those string operations.

Hope this helps

2 Likes

I will try and implement this when I get home.

1 Like
local function getPointDistance(TargetPointPosition, PointsDic)
	
	local ClosestPoint = PointsDic[1]
	local ClosestPointNum = 1
	for key, pointPos:Vector3 in PointsDic do
		if (pointPos-TargetPointPosition).Magnitude < (pointPos-ClosestPoint).Magnitude then
			ClosestPoint = pointPos
			ClosestPointNum = key
		end
	end
	local LeftPoint
	local RightPoint
	
	if ClosestPointNum == 1 then
		RightPoint = PointsDic[2]
		LeftPoint = PointsDic[#PointsDic]
	elseif ClosestPointNum == #PointsDic then
		RightPoint = PointsDic[1]
		LeftPoint = PointsDic[ClosestPointNum-1]
	else
		LeftPoint = PointsDic[ClosestPointNum-1]
		RightPoint = PointsDic[ClosestPointNum+1]
	end
	--print(ClosestPointNum, ClosestPoint, RightPoint, LeftPoint)
	local PointDistance
	
	local sideA, sideB, sideC = SidesOfATriangle(ClosestPoint, RightPoint, TargetPointPosition)
	local RightPointTri = checkForRightAngle(sideA, sideB, sideC)
	local LeftPointTri
	if RightPointTri then
		PointDistance = calulateHeightOfTriangle(sideA, sideB, sideC)
	else
		sideA, sideB, sideC = SidesOfATriangle(ClosestPoint, LeftPoint, TargetPointPosition)
		LeftPointTri = checkForRightAngle(sideA, sideB, sideC)
		if LeftPointTri then
			PointDistance = calulateHeightOfTriangle(sideA, sideB, sideC)
		end
	end
	
	if PointDistance == nil then
		PointDistance = (ClosestPoint-TargetPointPosition).Magnitude
	end
	
	return PointDistance
end

So here is the revised coded I made it into a function because of the usage I’ll be using it for.

2 Likes

You should separate it into smaller functions, like getSomethingValue or calculatePointDistance, this will make it a lot more redable

There is a principle that tells the code should be shorter for the more complex it is, this might help you, because if something is very complex, you should try to split it into it’s own function

For instance, in your case there are many for loop math calculations and elseif block, you can simply put those in separate function, and make it a lot cleaner

You can turn getting pointPos into another function, that will base off table you’ll provide and other variables

This way your code should look a lot better

2 Likes

Concatenation is only slow with large strings, "Point"..1 is not a large string.

Yes but indexing and numeric operations are still faster than concantenation.

Yea I have to agree with you on that one

Rn Ive changed my use case so it’s only a dictionary of vectors