all groups > dotnet performance > october 2007 >
You're in the

dotnet performance

group:

Clone vs New?


Re: Clone vs New? Laura T.
10/2/2007 12:00:00 AM
dotnet performance:

"schneider" <eschneider@ooooooooo.com> ha scritto nel messaggio
news:emvRHGLBIHA.3716@TK2MSFTNGP03.phx.gbl...
[quoted text, click to view]

Depends of it is implemented.
Cloning and copying are two different things, but most of the time they are
implemented in the same way (object!=object.clone()).
For example, the string.clone() returns a reference to the same string. As
strings are immutable, this is quite correct.
The stack collection instead does a deep copy, by creating a new object and
then copying the array inside it,
so there is no performance difference here with creating new or cloning.
The generic collections do not even have a clone() method.
Most of the System.Drawing objects implement Clone() as creating a copy of
the instance, so no difference here either.
Clone vs New? schneider
10/2/2007 12:07:57 AM
It seems that in some cases its quicker to clone an existing object vs
creating a new object. I have not done exstensive perf test but have found
cases where it helps.

Anyone have any thoughts on this?
Why would this be true?
Is it always true? if not then why not?

Thanks,

Schneider

Re: Clone vs New? Chris Mullins [MVP - C#]
10/2/2007 10:38:04 AM
Laura's answer is dead on - Cloning & Creating a new Instance are two very
different things with very different use cases.

In a number of projects I work on, we built the cornerstone of our
algorithms on the Prototype Pattern, which is a Clone() based
implementation. Cloning is great, and has a wide variety of use cases.

In most cases though, cloning is going to be quite a bit slower than
creating a new instance. The code for cloning is often going to look like:

public object Clone()
{
Foo o = new Foo();
o.ListOfNames = this.ListOfNames;
o.Owner = this.Owner;
return o;
}

This is clearly slower than just creating a new instance of Foo, as more
stuff is going on. As Cloning gets more complex (as it always does) it's not
uncommon to use Xml or binary Serialization, or even (and this is bad!) do a
database dip.

Note: The above code has a subtle bug that often bites people. Both copies
(old and new) point to the same instance of ListOfNames & Owner. In the case
of the string (Owner) this may not be a problem, as strings are immutable,
but for many other things (Lists, Dictionaries, Datasets, etc), it's a
catastrophic and subtle bug. If someone goes "old.ListOfNames.Clear()" both
instances are affected.

Anyone know why Microsoft never made a Generic IClonable? This always seemed
silly, as IClonable<T> would eliminate the cast that always happens on
clone. I usually end up with two methods:

public object Clone(){}
public MyType CloneAsMyType() { return (MyType) Clone());}

--
Chris Mullins

[quoted text, click to view]

Re: Clone vs New? Chris Mullins [MVP - C#]
10/2/2007 11:34:17 AM
If you want the same object with no state, I would go with "new" every time.

Often the right high level option is to use a Factory Pattern, which
abstracts this from your code:
MyObject o = MyObjectFactory.CreateMyObject();

That way you can implement the creation logic any which way.

--
Chris Mullins

[quoted text, click to view]

Re: Clone vs New? schneider
10/2/2007 1:10:17 PM
I understand your points.

assuming I wanted the same object with no state, would it be faster to clone
vs create?

I guess i'm wondering if it does any optimization because it knows more
about what the end goal is? Like it has a good idea of memory required,
security.





[quoted text, click to view]

Re: Clone vs New? schneider
10/2/2007 1:58:49 PM

Agreed I'm already using the Factory pattern, just looking to squeeze out
more performance.

In my factory I'm already using a clone which seems to help, but it is
probably due to prevented initialization of private member variables, and
not .Net optimization.

Thanks,
Schneider

[quoted text, click to view]

Re: Clone vs New? schneider
10/3/2007 10:24:10 AM
I understand the issues with cloning, this thread was to help me determine
if there is any .NET optimizations performed when cloning objects, seems
there is not, which I think that it could.
But there can be some performance improvements due to any object
inializations performed.

public class ColorTheme{

private m_color1=SystemColors.Control;

private m_color2=SystemColors.ControlDark;

}

Thanks,
Schneider

[quoted text, click to view]

Re: Clone vs New? Laura T.
10/3/2007 2:05:20 PM
I guess the problem with generics cloning comes from the possibility that a
<T> might not be cloneable.
Another point is the semantic mismatch of ICloneable interface.. does it
mean shallow/deep?

You can read a very good discussion here:

http://blogs.msdn.com/brada/archive/2004/05/03/125427.aspx

More interesting cloning subtleties:

http://blogs.msdn.com/abhinaba/archive/2006/04/19/578518.aspx

"Chris Mullins [MVP - C#]" <cmullins@yahoo.com> ha scritto nel messaggio
news:OtKtfrRBIHA.3916@TK2MSFTNGP02.phx.gbl...
[quoted text, click to view]
Re: Clone vs New? Adrian Gallero
10/3/2007 4:09:38 PM
Hi,

[quoted text, click to view]

As other people said, clone is just a method and it being faster of not
depend on what the method does.
If your object implements clone like this:

public object() Clone
{
return this;
}

It will be faster than creating a new instance, because it is not
actually doing so.

But there is other thing not mentioned here that might be interesting
to note.

This is a common implementation of Clone():

public object() Clone
{
return MemberwiseClone();
}

This will return a new instance of the object with all the fields
copied (shallow copy) from the original, so in many ways is similar to
calling new and copying the fields.
Now the interesting thing (and that might be cause of many subtle bugs)
is that MemberwiseClone will *not* call the constructor method on the
new object.

If the constructor of your object is something like this:
public MyObject()
{
SomeVerySlowThings();
}

Then cloning will be faster than creating a new instance, since
SomeVerySlowThings() will not be called when creating the copy.
Again, note that this behavior might not be what you want, so you need
to take a lot of care when using MemberwiseClone(), and make sure any
important logic that should be done for each object is called in the
clone method besides the constructor. You will probably need to call
VerySlowThings in Clone() too.


As a way to clarify all of this, here is a simple console app:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Stating test");
MyObject o = new MyObject();
Console.WriteLine("Object 1 has been created");
MyObject o2 = o.Clone() as MyObject;
Console.WriteLine("Object 1 has been cloned");
}
}

class MyObject : ICloneable
{
public MyObject()
{
Console.WriteLine("Entering constructor");
}


#region ICloneable Members

public object Clone()
{
return MemberwiseClone();
}

#endregion
}
}

If you look at the result, you will see that the "Entering constructor"
is printed only when creating the object, but not when cloning it.

If whatever goes in the constructor is slow, clone will be faster.

Regards,
AddThis Social Bookmark Button