How could i optimize this RunService script

i was just wondering if there’s any way to optimize this script with RunService loop, it’s activity is at 30+ when working on 3600 parts at a time, the script is ran on the client. Any help is appreciated

local WavePatternFolder = workspace:WaitForChild("WavePattern")
local PatternModels = WavePatternFolder:GetChildren()
table.sort(PatternModels, function(a, b)
	return tonumber(a.Name) > tonumber(b.Name)
end)

local Parts = {}

for i,Model in pairs(PatternModels) do
	local FoundParts = Model:GetChildren()
	table.sort(FoundParts, function(a, b)
		return tonumber(a.Name) > tonumber(b.Name)
	end)
	table.insert(Parts, FoundParts)
end

local Sound = workspace.MusicSound

local step = 0

local minimumColorMultiplier = 0.35
local ColorMultiplier

game:GetService("RunService").Heartbeat:Connect(function(currentTime, deltaTime)
	step += 1
	if step%2 == 0 then
		--ColorMultiplier = Sound.PlaybackLoudness/600
		--if ColorMultiplier <= minimumColorMultiplier then
		--	ColorMultiplier = minimumColorMultiplier
		--end
		for i,_ in pairs(Parts) do
			if i == #Parts then
				for i2 = 1, #Parts[i] do
					if i2 == #Parts[i] then
						Parts[i][i2].Color = 
							Color3.fromRGB(255 * Sound.PlaybackLoudness/600,0,0)
					else
						Parts[i][i2].Color = Parts[i][i2 + 1].Color 
					end
				end
			else
				for i2 = 1, #Parts[i] do
					if i2 == #Parts[i] then
						Parts[i][i2].Color = Parts[i+1][#Parts[i+1]].Color
					else
						Parts[i][i2].Color = Parts[i][i2 + 1].Color 
					end
				end
			end
		end
	end
end)

I would recommend sampling the colors from a limited palette instead of constantly creating color3s so the GC has time to recover. though I really don’t know if it’d be worth it cause i cant tell how many times you are calling it but I found creating a color3 millions of times a frame to cause some memory issues which led to me crashing.