Solid Modelling multiple parts on a script optimization

When solid modelling via a plugin, the process it takes to arrange the model I’m working on is almost instantaneously.
Currently, to get the same result with the plugin, I have to spam the “SubtractAsync” method for each part within a model whereas using the plugin, I just negate one of the blocks & union them all together.
My current model is about 37 parts & spamming SubtractAsync yields the thread by ~3 seconds due to the calculations it has to go through.

My question is, is it possible that i’m making incorrect use of the SubtractAsync method, and is there a way to up the result performance?

Here’s my code:

local Model		= workspace.MyModel
local Origin	= Model:GetModelCFrame()
local Scale		= Model:GetModelSize()
local PlaneCF	= Origin * CFrame.Angles(0, 0, math.pi/4)

local p		= Instance.new("Part")
p.Size		= Scale * 4
p.CFrame	= PlaneCF * CFrame.new(0, -Scale.Y*2, 0)

local p1	= p:Clone()
p1.CFrame	= PlaneCF * CFrame.new(0, Scale.Y*2, 0)


local ModelCache	= Model:GetChildren()
local Upper, Lower	= {	}, { }

local t	= tick()
for i, hit in next, ModelCache do
		local Part0, Part1 do
			--pcall(function()
			
			local idk	= Model:GetDescendants()
			local a	= hit:SubtractAsync({p})--hit:SubtractAsync({p}, "Hull")
			local b	= hit:SubtractAsync({p1})--hit:SubtractAsync({p1}, "Hull")
			
			Part0	= a--:UnionAsync({hit})
			Part1	= b--:UnionAsync({hit})
			--end)
		end
		
		if Part0 and Part1 then
			Part0.CFrame	= Origin * Origin:ToObjectSpace(Part0.CFrame)
			Part1.CFrame	= Origin * Origin:ToObjectSpace(Part1.CFrame)
			Part0.Anchored, Part1.Anchored	= true, true
			Part0.Parent, Part1.Parent = Model, Model
			
			table.insert(Lower, Part0)
			table.insert(Upper, Part1)
		elseif Part0 then
			Part0.CFrame	= Origin * Origin:ToObjectSpace(Part0.CFrame)
			Part0.Anchored	= true
			Part0.Parent	= Model
			table.insert(Lower, Part0)
		elseif Part1 then
			Part1.CFrame	= Origin * Origin:ToObjectSpace(Part1.CFrame)
			Part1.Anchored	= true
			table.insert(Upper, Part1)
		end
		hit:Destroy()
end
print(tick()-t)

Considering SubtractAsync takes a table of objects, couldn’t you pass the entire list of parts into it?