:Clone() or :Instance.New()?

Hello, making a gun system here. Replicating a lot of bullets(30 bullets a mag). My question is simple

Does Clone() or Instance.New() create less lag?
Which one is more efficient.
And which one should I use and why?

If both have their perks please do explain.

7 Likes

Personally, I prefer prefabricating and then using :Clone().

It keeps your code cleaner and less cluttered, and I think it’s faster since you don’t have to keep setting the properties every time you create one.

The difference is probably minor, so you could do whichever you prefer without much performance loss.

8 Likes

Clone is faster apparently (Just tested for you with the following code):

local start = tick();
local p = Instance.new'Part';
p.Parent = workspace;
p.Anchored = true;
p.BrickColor = BrickColor.new('Bright red')--adding few properties to test the thing out
p.Locked = true;
print('Part created in '.. tick()-start..' seconds');
start = tick();
local clone = p:Clone();
clone.Parent = workspace;
print('Part cloned in '.. tick()-start..' seconds');

image

6 Likes

Your benchmark is flawed and even if it wasn’t, running it once doesn’t help much. And it’s also incorrect, :Clone is slow.

image
image

And as for OP, you should use PartCache instead. Neither of these are optimal, but PartCache is.

19 Likes

I feel like benchmarking these is absolutely pointless in this scenario because benchmarking isn’t representative of a real world application. Worrying about which one is faster is also pointless, it’s not like you’re saving significant amounts of time.

Just use whichever one is more comfortable for you. Just because one runs slower, doesn’t mean it creates lag. What matters is how you handle those parts later. Ultimately for both cloning and instancing, the new object is just a piece of memory detached from the DataModel that you’re modifying.

Only perk difference I can think of is that you’re going to feel more comfortable with clone because you’re copying something that’s already been made. If you instance the part, then you have to write out all the configurations and all.

21 Likes

Thanks for the info on PartCache, I never knew something like that existed.
I’m not an expert in these things and it might take me alot of time to get familiar with PartCache, Do you think it’s worth learning about it?

It is. Definitely check it out because recreating Instances sucks.

3 Likes

I don’t see a reason for the benchmark to be inaccurate.

My benchmarks show that :Clone() is about 40% slower than Instance.new(), even when setting 5 properties.

2 Likes

What is “prefabricating”? I couldn’t find any documentation, is this where you would create your own instanced part then clone based off that?

Yes it is also this post is a little outdated because now we have Instance.fromExisting
Which should be faster than clonning because it creates shallow copy without deep clonning

2 Likes

local Clone = game.Clone

local test = Clone(workspace.Baseplate)

Dirrectly calling clone would be more fair than Dirrectly calling instance new

2 Likes

is .fromExisting literally just a better game.clone(inst)

it doesn’t match clone, it clones the passed instance with default properties

no misinformation please

2 Likes

Crazy reply to someone just trying to prove you wrong fr.

Also for this post made by OP, use Instance.fromExisting() if you dont wanna use a part cache. Otherwise, part cache is your best bet at optimal performance.

1 Like

I should probably repeat the benchmark but comparing Instance.fromExisting() versus Instance.new()

I came upon this post and wanted to double check if :Clone() was actually slower in a real-world environment. Below are the timed results of three functions, each creating 256 parts with various properties changed, run five times.

For Instance.new

0.0027773380279541016
0.0024547576904296875
0.0025026798248291016
0.0026025772094726562
0.0024390220642089844

For :Clone()

0.003247976303100586
0.0029532909393310547
0.0030412673950195312
0.0029115676879882812
0.003021240234375

For Instance.fromExisting

0.0029854774475097656
0.002967357635498047
0.003371000289916992
0.002826213836669922
0.0026302337646484375

Just for the record - and for the sake of any developers like me who stumbled upon this wondering which would be best for performance - Instance.new is still faster. Instance.fromExisting is 2nd with :Clone() not far behind it.

If you would like to fact-check, the script I used is below. This is ripped from a game I’m devving (yay real world testing), so you’ll need to add a folder named “Map” (or just remove those parts so it gets parented to workspace). Uncomment one comment block at a time each time you run it to test the three methods.

function createWindowPieces()
	local start = tick()
	
	--[[
	for i = 1, 256 do
		local part = Instance.new("Part")
		part.Size = Vector3.new(.25, .25, .25)
		part.Color = Color3.new(0, 1, 1)
		part.Transparency = .75
		part.Position = Vector3.new(61.75, 7, -57)
		part.Parent = workspace.Map
		part:ApplyImpulse(Vector3.new(math.random(-1, 1), math.random(-1, 1), math.random(-1, 1)))
	end
	]]
	
	--[[
	local part = Instance.new("Part")
	part.Size = Vector3.new(.25, .25, .25)
	part.Color = Color3.new(0, 1, 1)
	part.Transparency = .75
	part.Position = Vector3.new(61.75, 7, -57)
	part.Parent = workspace.Map
	part:ApplyImpulse(Vector3.new(math.random(-1, 1), math.random(-1, 1), math.random(-1, 1)))
	
	for i = 1, 255 do
		local newPart = part:Clone()
		newPart.Parent = workspace.Map
	end
	]]
	
	----[[
	local part = Instance.new("Part")
	part.Size = Vector3.new(.25, .25, .25)
	part.Color = Color3.new(0, 1, 1)
	part.Transparency = .75
	part.Position = Vector3.new(61.75, 7, -57)
	part.Parent = workspace.Map
	part:ApplyImpulse(Vector3.new(math.random(-1, 1), math.random(-1, 1), math.random(-1, 1)))

	for i = 1, 255 do
		local newPart = Instance.fromExisting(part)
		newPart.Parent = workspace.Map
	end
	--]]
	
	print(tick() - start)
	task.wait(1)
end

createWindowPieces()
createWindowPieces()
createWindowPieces()
createWindowPieces()
createWindowPieces()
1 Like

that a very unrealistic and even more so not legitimate benchmark.
Manually setting properties will be slower in 100% and more so you must instead get avarage results;
tick() is not accurate and you always should use os.clock instead
Instance.fromExisting wins always in 100% if use realistic use cases.
Plus you most of the time dont have default properties of an instance

Edit:
nvm

  1. New: 0.0008282399270683527
  2. FromExisting: 0.0012399000581353903
  3. Clone: 0.0015072999987751246
Code
--!strict
--!optimize 2
--!native
local prt:Part = Instance.new("Part")
prt.Anchored=true
prt.Color=Color3.new(1,0,0)
prt.TopSurface=Enum.SurfaceType.Smooth
prt.BottomSurface=Enum.SurfaceType.Smooth
prt.CFrame=CFrame.identity
prt.Size=Vector3.one


local t:number = 0

task.wait(0.1)
t=0
for j=1,5 do
	local a:number = os.clock()
	for i=1,256 do
		Instance.fromExisting(prt)
	end
	t+=os.clock()-a
end
print(`FromExisting: {t/5}`)
task.wait(0.1)
local Clone = game.Clone
t=0
for j=1,5 do
	local a:number = os.clock()
	for i=1,256 do
		Clone(prt)
	end
	t+=os.clock()-a
end
print(`Clone: {t/5}`)

task.wait(0.1)
t=0
for j=1,5 do
	local a:number = os.clock()
	for i=1,256 do
		local prt:Part = Instance.new("Part")
		prt.Anchored=true
		prt.Color=Color3.new(1,0,0)
		prt.TopSurface=Enum.SurfaceType.Smooth
		prt.BottomSurface=Enum.SurfaceType.Smooth
		prt.CFrame=CFrame.identity
		prt.Size=Vector3.one
	end
	t+=os.clock()-a
end
print(`New: {t/5}`)

It is probably the case becouse Instance.fromExisting does all checks manually and setting properties in code applies some Luau optimizations

But once again lets be honest that we all would either use :Clone or fromExisting in a real code.

What do you mean unrealistic, this is a function I must use in an actual game. That’s about as realistic as it gets - “real world example.” I added the manually set properties to see if either method of rapidly creating new parts performed better/worse if the duplicating part had some applied properties - like you’d have in an actual game.

In what scenario would you not have the properties of an Instance that you are duplicating??

You can use any of the three. The performance impact is marginal. But if you need to rapidly create large batches of parts - use Instance.new and set the properties for each manually.

1 Like