Skip to content

Instantly share code, notes, and snippets.

@OverHash
Created August 25, 2021 07:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OverHash/8144d5cf8ed5a9fd29479653175c5589 to your computer and use it in GitHub Desktop.
Save OverHash/8144d5cf8ed5a9fd29479653175c5589 to your computer and use it in GitHub Desktop.
Performance testing Roblox's new OverlapParams functions.
local Workspace = game:GetService("Workspace")
local PART_SIZES = { 0, 25, 100, 1000, 5000, 10000 }
local hitbox = Workspace:FindFirstChild("Hitbox")
local hitboxCf = hitbox.CFrame
local hitboxSz = hitbox.Size
local start = hitbox.CFrame * CFrame.new(hitbox.Size / 2)
local finish = hitbox.CFrame * CFrame.new(-hitbox.Size / 2)
local overlap = OverlapParams.new()
local region = Region3.new(start.Position, finish.Position)
local random = Random.new()
for _, size in ipairs(PART_SIZES) do
local descendants = {}
for _ = 1, size do
local newPart = Instance.new("Part")
newPart.CFrame = hitbox.CFrame * CFrame.new(
hitbox.Size.X * random:NextNumber(-0.5, 0.5),
hitbox.Size.Y * random:NextNumber(-0.5, 0.5),
hitbox.Size.Z * random:NextNumber(-0.5, 0.5)
)
newPart.Anchored = true
newPart.Size = Vector3.new(2, 2, 2)
newPart.Transparency = 0.5
newPart.Color = Color3.fromRGB(255, 255, 255)
newPart.Parent = Workspace
table.insert(descendants, newPart)
end
for i = 1, 2 do
local useNewApi = i % 2 == 0
-- small wait before we perform benchmark for any expensive operations to finish
task.wait(2)
-- perform benchmark
local start = os.clock()
for _ = 1, 100 do
if useNewApi then
Workspace:GetPartBoundsInBox(hitboxCf, hitboxSz, overlap)
else
Workspace:FindPartsInRegion3(region)
end
end
print(size, string.format("%0.4fms", (os.clock() - start) * 1000), useNewApi)
end
-- GC instances
for _, part in ipairs(descendants) do
part.Parent = nil
end
task.wait(5)
end
Similar format results to before, where the first number indicates the amount of parts, second is the amount of milliseconds for 100 API calls, third element is if GetPartBoundsInBox is used (true) or FindPartsInRegion3 is used (false):
0 0.1535ms false
0 0.3553ms true
25 0.1393ms false
25 1.7630ms true
100 0.0809ms false
100 5.3808ms true
1000 0.0638ms false
1000 61.0919ms true
5000 0.0899ms false
5000 514.3444ms true
10000 0.0638ms false
10000 1259.1286ms true
local Workspace = game:GetService("Workspace")
local PART_SIZES = { 0, 25, 100, 1000, 5000, 10000 }
local hitbox = Workspace:FindFirstChild("Hitbox")
local hitboxCf = hitbox.CFrame
local hitboxSz = hitbox.Size
local start = hitbox.CFrame * CFrame.new(hitbox.Size / 2)
local finish = hitbox.CFrame * CFrame.new(-hitbox.Size / 2)
local overlap = OverlapParams.new()
overlap.FilterType = Enum.RaycastFilterType.Whitelist
local region = Region3.new(start.Position, finish.Position)
local random = Random.new()
for _, size in ipairs(PART_SIZES) do
local descendants = {}
for _ = 1, size do
local newPart = Instance.new("Part")
newPart.CFrame = hitbox.CFrame
* CFrame.new(
hitbox.Size.X * random:NextNumber(-0.5, 0.5),
hitbox.Size.Y * random:NextNumber(-0.5, 0.5),
hitbox.Size.Z * random:NextNumber(-0.5, 0.5)
)
newPart.Anchored = true
newPart.Size = Vector3.new(2, 2, 2)
newPart.Transparency = 0.5
newPart.Color = Color3.fromRGB(255, 255, 255)
newPart.Parent = Workspace
table.insert(descendants, newPart)
end
-- add a random 25 parts to our FilterDescendantsInstances
local filterDescendants = table.create(#descendants)
for i = 1, math.min(size, 25) do
table.insert(filterDescendants, descendants[i])
end
overlap.FilterDescendantsInstances = descendants
for i = 1, 2 do
local useNewApi = i % 2 == 0
-- small wait before we perform benchmark for any expensive operations to finish
task.wait(2)
-- perform benchmark
local start = os.clock()
for _ = 1, 100 do
if useNewApi then
Workspace:GetPartBoundsInBox(hitboxCf, hitboxSz, overlap)
else
Workspace:FindPartsInRegion3(region)
end
end
print(size, string.format("%0.4fms", (os.clock() - start) * 1000), useNewApi)
end
-- GC instances
for _, part in ipairs(descendants) do
part.Parent = nil
end
task.wait(5)
end
Similar format results to before, where the first number indicates the amount of parts, second is the amount of milliseconds for 100 API calls, third element is if GetPartBoundsInBox is used alongside FilterDescendantsInstances set to 25 parts (true) or FindPartsInRegion3 is used (false):
0 0.0708ms false
0 0.3183ms true
25 0.0760ms false
25 2.4035ms true
100 0.0624ms false
100 7.2634ms true
1000 0.1041ms false
1000 81.3375ms true
5000 0.0742ms false
5000 765.0460ms true
10000 0.0678ms false
10000 1717.8362ms true
local Workspace = game:GetService("Workspace")
local PART_SIZES = { 0, 25, 100, 1000, 5000, 10000 }
local hitbox = Workspace:FindFirstChild("Hitbox")
local hitboxCf = hitbox.CFrame
local hitboxSz = hitbox.Size
local start = hitbox.CFrame * CFrame.new(hitbox.Size / 2)
local finish = hitbox.CFrame * CFrame.new(-hitbox.Size / 2)
local overlap = OverlapParams.new()
overlap.MaxParts = 1
local region = Region3.new(start.Position, finish.Position)
local random = Random.new()
for _, size in ipairs(PART_SIZES) do
local descendants = {}
for _ = 1, size do
local newPart = Instance.new("Part")
newPart.CFrame = hitbox.CFrame
* CFrame.new(
hitbox.Size.X * random:NextNumber(-0.5, 0.5),
hitbox.Size.Y * random:NextNumber(-0.5, 0.5),
hitbox.Size.Z * random:NextNumber(-0.5, 0.5)
)
newPart.Anchored = true
newPart.Size = Vector3.new(2, 2, 2)
newPart.Transparency = 0.5
newPart.Color = Color3.fromRGB(255, 255, 255)
newPart.Parent = Workspace
table.insert(descendants, newPart)
end
for i = 1, 2 do
local useNewApi = i % 2 == 0
-- small wait before we perform benchmark for any expensive operations to finish
task.wait(2)
-- perform benchmark
local start = os.clock()
for _ = 1, 100 do
if useNewApi then
Workspace:GetPartBoundsInBox(hitboxCf, hitboxSz, overlap)
else
Workspace:FindPartsInRegion3(region)
end
end
print(size, string.format("%0.4fms", (os.clock() - start) * 1000), useNewApi)
end
-- GC instances
for _, part in ipairs(descendants) do
part.Parent = nil
end
task.wait(5)
end
Similar format results to before, where the first number indicates the amount of parts, second is the amount of milliseconds for 100 API calls, third element is if GetPartBoundsInBox is used alongside MaxParts set to 1 (true) or FindPartsInRegion3 is used (false):
0 0.1057ms false
0 0.9415ms true
25 0.1370ms false
25 1.1478ms true
100 0.0670ms false
100 2.0912ms true
1000 0.0869ms false
1000 19.3874ms true
5000 0.0662ms false
5000 103.2925ms true
10000 0.2380ms false
10000 213.2466ms true
local Workspace = game:GetService("Workspace")
local PART_SIZES = { 0, 25, 100, 1000, 5000, 10000 }
local hitbox = Workspace:FindFirstChild("Hitbox")
local start = hitbox.CFrame * CFrame.new(hitbox.Size / 2)
local finish = hitbox.CFrame * CFrame.new(-hitbox.Size / 2)
local overlap = OverlapParams.new()
local region = Region3.new(start.Position, finish.Position)
local random = Random.new()
for _, size in ipairs(PART_SIZES) do
local descendants = {}
for _ = 1, size do
local newPart = Instance.new("Part")
newPart.CFrame = hitbox.CFrame * CFrame.new(
hitbox.Size.X * random:NextNumber(-0.5, 0.5),
hitbox.Size.Y * random:NextNumber(-0.5, 0.5),
hitbox.Size.Z * random:NextNumber(-0.5, 0.5)
)
newPart.Anchored = true
newPart.Size = Vector3.new(2, 2, 2)
newPart.Transparency = 0.5
newPart.Color = Color3.fromRGB(255, 255, 255)
newPart.Parent = Workspace
table.insert(descendants, newPart)
end
for i = 1, 2 do
local useNewApi = i % 2 == 0
-- small wait before we perform benchmark for any expensive operations to finish
task.wait(2)
-- perform benchmark
local start = os.clock()
for _ = 1, 100 do
if useNewApi then
Workspace:GetPartsInPart(hitbox, overlap)
else
Workspace:FindPartsInRegion3(region)
end
end
print(size, string.format("%0.4fms", (os.clock() - start) * 1000), useNewApi)
end
-- GC instances
for _, part in ipairs(descendants) do
part.Parent = nil
end
task.wait(5)
end
The first number indicates the amount of parts, second is the amount of milliseconds for 100 API calls, third element is if GetPartsInPart is used (true) or FindPartsInRegion3 is used (false):
0 0.0778ms false
0 0.4018ms true
25 0.0913ms false
25 6.1577ms true
100 0.0825ms false
100 21.1336ms true
1000 0.0768ms false
1000 240.5298ms true
5000 0.0632ms false
5000 1459.7305ms true
10000 0.0665ms false
10000 3090.1008ms true
local Workspace = game:GetService("Workspace")
local PART_SIZES = { 0, 25, 100, 1000, 5000, 10000 }
local hitbox = Workspace:FindFirstChild("Hitbox")
local hitboxCf = hitbox.CFrame
local hitboxSz = hitbox.Size
local r = hitboxSz.X
local hitboxPos = hitboxCf.Position
local overlap = OverlapParams.new()
local random = Random.new()
for _, size in ipairs(PART_SIZES) do
local descendants = {}
for _ = 1, size do
local newPart = Instance.new("Part")
newPart.CFrame = hitbox.CFrame
* CFrame.new(
hitbox.Size.X * random:NextNumber(-0.5, 0.5),
hitbox.Size.Y * random:NextNumber(-0.5, 0.5),
hitbox.Size.Z * random:NextNumber(-0.5, 0.5)
)
newPart.Anchored = true
newPart.Size = Vector3.new(2, 2, 2)
newPart.Transparency = 0.5
newPart.Color = Color3.fromRGB(255, 255, 255)
newPart.Parent = Workspace
table.insert(descendants, newPart)
end
for i = 1, 2 do
local useNewApi = i % 2 == 0
-- small wait before we perform benchmark for any expensive operations to finish
task.wait(2)
-- perform benchmark
local start = os.clock()
for _ = 1, 100 do
if useNewApi then
Workspace:GetPartBoundsInRadius(hitboxPos, r, overlap)
else
Workspace:GetPartBoundsInBox(hitboxCf, hitboxSz, overlap)
end
end
print(size, string.format("%0.4fms", (os.clock() - start) * 1000), useNewApi)
end
-- GC instances
for _, part in ipairs(descendants) do
part.Parent = nil
end
task.wait(5)
end
I ran these on a Hitbox with size 50, 50, 50
Similar format results to before, where the first number indicates the amount of parts second is the amount of milliseconds for 100 API calls third number is if GetPartBoundsInRadius is used (true) or GetPartBoundsInBox is used (false):
0 0.5943ms false
0 0.8691ms true
25 2.1426ms false
25 2.3293ms true
100 5.0867ms false
100 4.4336ms true
1000 47.9035ms false
1000 34.5973ms true
5000 606.7480ms false
5000 637.8543ms true
10000 1367.7854ms false
10000 997.0864ms true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment