Using Instance.new("Object", parent) bad?

I was not stating a argument, but a opinion. I get where you stand. As mentioned it have performance differences, even minor as it may be :slight_smile:

I disagree. The reason why this is bad is because once you have set the parent, the object is now active, meaning a lot of events are being fired, such as rendering to every client. You would usually set the parent after setting the properties that you want. But that is entirely up to the individual; if he or she wants a better performance, then setting the parent last is the best option; if you don’t care about performance, then that is entirely up to you.

If you are not setting any properties then of course Instance.new(className, parent) would be better.

This pretty much is a moot point. One way takes longer by 0.0000001 of a second, and the other is built into the command. Think the difference would be no real difference. As far as performance drop, I didn’t find anything myself. It may on some other rig. Roblox Documentation list the two stage set up.

if u gonn make quick things like attachments or sum that dont need property changing u can use parent argument aka like this

local attachment = Instance.new("Attachment",part)

but if u gonn change properties then nah dont use it aka

local attachment = Instance.new("Attachment",part)
attachment.Position = Vector3.new(1,0,0)

ye just dont do that use this instead

local attachment = Instance.new("Attachment")
--properties
attachment.Parent = part

there aint no noticeable difference though like even slightly so do as u please this is just recommended by people fsr

2 Likes

I’m going to ignore the replies and comment directly on what you asked.

It’s not so much of a “fix” as it is “how it works.”

The issue is that when you parent an object, it is now under the datamodel and its changes must be calculated each time it actually changes.

So, if you’re creating a new Instance that you want to have some basic properties set, i.e. CFrame/Position/Size/Color/etc…
You shouldn’t parent it when instantiating it using the second parameter of Instance.new()

Instead, we do this:

local Part = Instance.new("Part") -- Don't parent it yet.
Part.CFrame = CFrame.new(0,20,0) -- We'll have a part 20 studs in the sky
Part.Anchored = true -- Anchored
Part.Size = Vector3.new(5,5,5) -- And it will be a cube of size 5.
Part.Parent = workspace -- Now parent it to workspace.

This results in a Part of size 5,5,5 at position 0,20,0 that is Anchored being created upon it being parented.

What changes if we don’t do it like this and instead like this?

local Part = Instance.new("Part", workspace) -- Parent it
Part.CFrame = CFrame.new(0,20,0) -- set the CFrame to 20 studs in the sky
Part.Anchored = true -- Anchor it
Part.Size = Vector3.new(5,5,5) -- Set the size

Notice how most of the context went from “it will be” to “it is now?”
Because we parented it, we’re now contextualizing all the subsequent changes as subsequent and present. We’re changing the part under the datamodel (and consequently its internal simulation characteristics) with each property change.

When you wait to parent the object, the DataModel doesn’t have any interaction with it yet, and so it’s not simulated, rendered, or likewise.
Essentially, if you wait to parent it, you’re just modifying a table of “what it will be” properties, and when it’s parented those “what it will be” properties become “what it is.”

So basically, you’re not updating the datamodel and its simulations if you wait to parent it.

It’s also more performant due to the fact changing some properties when parented results in you updating the instances simulation characteristics and requires a re-computation; which takes up more performance internally.

6 Likes

Honsently they could just do

local stringVal = Instance.new("StringValue", workspace).Value = "talent hub bad"
--If your looking to change the parent THEN use stringVal.Parent and dont bomb me with random replies and attack me

I’m sorry but that code doesn’t work.

But this works.
local stringVal = Instance.new(“StringValue”, nil) stringVal.Name = “sdfksflsfsjfksfjksfsf” stringVal.Parent = game.Workspace

1 Like

Like the post you linked stated, using the second parameter of Instance.new() is highly not recommended by Roblox, you can even read the creator documentation as that is stated there.

You can even make a little test using os.clock():

local function testParameter()
	local debugTime = os.clock()
	
	local newPart = Instance.new("Part", workspace)

	return os.clock() - debugTime
end

local function testProperty()
	local debugTime = os.clock()
	
	local newPart = Instance.new("Part")
	newPart.Parent = workspace

	return os.clock() - debugTime
end


local parameterResult = testParameter()
local propertyResult = testProperty()

if parameterResult < propertyResult then
	print("Parameter was faster")
else
	print("Property was faster")
end
print()
print("parameter: ", parameterResult)
print("property: ", propertyResult)

Please just change the parent normally, as that’s not really a lot of work for better performance.

Parenting normally seemed to execute around 80% faster.

4 Likes

Generally, keep it like this:

local part = Instance.new("Part")
part.Transparency = 1
part.Name = "Beans"
part.Parent = workspace

Not this:

local part = INstance.new("Part",workspace)
part.Transparency = 1
part.Name = "Beans"

This would also apply to instances that normally probably won’t cause alot of issues like value instances. (This helps made code more readable/consistent as compared to just making it performant though this honestly is a personal readability choice, correct me If I’m wrong of course)

This is due to the fact of the way it is ran.
When you use the second argument in Instance.new(), it will create the part (the first argument) and then right afterwards, parent it straight into the location you choose. This is bad for numerous of reasons, being of which:

It has to update its visuals, events, and connections tied to that object the moment it is born into existence. Changing a part when it “doesn’t exist” in workspace compared to when it does exist in workspace can have drastically different performance results.

Take for example a part I create and I change its transparency and color. It’ll go something like this if I parent after I change all the properties:

Create Part
Change Part transparency
Change Part Color
Change Part Name
Parent Part into Workspace
Render Part Color and Transparency
Connect events, physics, and other junk for part to work properly.

Compared to parenting it as soon as its born:

Create Part
Parent to Workspace
Render Part Color and Transparency (yes it has default properties)
Connect events, physics, and other junk for part to work properly.
Change Part Color – It actually might have to rerender at this part since the code goes from top to bottom. Though I don’t know the specifics to the system.
Change Part Transparency – It actually might have to rerender at this part since the code goes from top to bottom. Though I don’t know the specifics to the system.
Change Part Name
Render Part Color and Transparency

As you can see, it has to rerender it multiple times as opposed to just once, adding unnecessary amounts of computation to the mix.

4 Likes

I get what you mean, but aren’t those changes going to be fired so fast you wouldn’t even notice a difference? Or for example, if you create a part. It’s default of grey, and change the color after parenting. Would you see the color difference upon spawn? Or would it be so fast you don’t see it. Regardless I get what you mean.

See, it’s like 1 tenth of a millisecond difference. So I don’t really get the performance issue here. The only thing I wonder is if there is noticeable differences. Like a new part being the shape of a brick and grey, and you change scale and color after parent. Would you notice that on your client. If so, then I get that. But that’s more render issue, not performance issue.

So I think at that point it would matter if the player sees the Instance right away or not.

I’ve seen all the replies you’ve got on the thread. How come you’re still not satisfied with the feedback you’ve gotten? Sorry if I misinterpreted that. :slight_smile:

I am telling you what’s the better option based on that small test and Roblox’s recommendation, if you still insist on using the second parameter for the sake of “saving time” then that’s up to you.

No I mean I was responding to this: Like the post you linked stated, using the second parameter of Instance.new() is highly not recommended by Roblox

Seems like highly recommended seems a bit odd for how small of a performance difference it is.

Well I asked a question, that’s why I responded? lol

Re: " The only thing I wonder is if there is noticeable differences. Like a new part being the shape of a brick and grey, and you change scale and color after parent. Would you notice that on your client. If so, then I get that. But that’s more render issue, not performance issue."

I was referring to the ongoing discussion back and forth as a general in the thread, not directly the reply, I was replying to. That was for tagging you. But if your intention is to have an ongoing discussion, then go for it. I just thought you wanted replies on your original question, which you have gotten a lot of. :slight_smile:

Performance is not the only reason, you can read @3rdhoan123’s post and the original post you linked.

YOU do not need to create a poll to figure out which parent argument is the best at first hand obviously setting the parent lastly its the best thing you can do.

This post explicitly stats that option 2 is worse than option 1 and that option 3 is by far the worse option you can use therefore like I said option 1 is the best no need to debate here.

1 Like

Untrue, it can actually be significant. I’ve run this benchmarking code

local start = tick()
for i = 1, 1000 do
	local part = Instance.new("Part")
	part.Name = "Object" .. i
	part.Size = Vector3.new(
		math.random(1, 10),
		math.random(1, 10),
		math.random(1, 10)
	)
	part.Position = Vector3.new(
		math.random(1, 10),
		math.random(1, 10),
		math.random(1, 10)
	)
	part.Color = Color3.fromRGB(
		math.random(0, 255),
		math.random(0, 255),
		math.random(0, 255)
	)
	part.Parent = workspace
end
print(tick() - start)

start = tick()
for i = 1, 1000 do
	local part = Instance.new("Part", workspace)
	part.Name = "Object" .. i
	part.Size = Vector3.new(
		math.random(1, 10),
		math.random(1, 10),
		math.random(1, 10)
	)
	part.Position = Vector3.new(
		math.random(1, 10),
		math.random(1, 10),
		math.random(1, 10)
	)
	part.Color = Color3.fromRGB(
		math.random(0, 255),
		math.random(0, 255),
		math.random(0, 255)
	)
end
print(tick() - start)

And here are my results from 3 separate tests

  19:50:47.232  0.011055469512939453  -  Server - Script:22
  19:50:47.339  0.10613512992858887  -  Server - Script:44

  19:52:26.516  0.013800621032714844  -  Server - Script:22
  19:52:26.532  0.015799999237060547  -  Server - Script:44

  19:52:26.516  0.013800621032714844  -  Server - Script:22
  19:52:26.532  0.015799999237060547  -  Server - Script:44

sometimes it can be really significant, but in all cases it’s slower to use option 2. I’m pretty sure tick() isn’t 100% reliable though but it’s generally just better practice to do the fastest thing, even if it takes 1 extra line of code. It’s more readable anyways. os.clock() shows similar results. Sometimes it can end up being twice as slow, which is… not good

edit: misread the initial point, I dunno why you would be making default parts but the performance hitch is from changing properties so it should be fine

3 Likes