Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Performance / October 2007

Tip: Looking for answers? Try searching our database.

Clone vs New?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
schneider - 02 Oct 2007 06:07 GMT
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
Laura T. - 02 Oct 2007 10:54 GMT
> 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
[quoted text clipped - 7 lines]
>
> Schneider

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.
Chris Mullins [MVP - C#] - 02 Oct 2007 18:38 GMT
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

> 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
[quoted text clipped - 7 lines]
>
> Schneider
schneider - 02 Oct 2007 19:10 GMT
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.

> Laura's answer is dead on - Cloning & Creating a new Instance are two very
> different things with very different use cases.
[quoted text clipped - 47 lines]
>>
>> Schneider
Chris Mullins [MVP - C#] - 02 Oct 2007 19:34 GMT
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

>I understand your points.
>
[quoted text clipped - 57 lines]
>>>
>>> Schneider
schneider - 02 Oct 2007 19:58 GMT
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

> If you want the same object with no state, I would go with "new" every
> time.
[quoted text clipped - 69 lines]
>>>>
>>>> Schneider
Laura T. - 03 Oct 2007 13:05 GMT
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

> Laura's answer is dead on - Cloning & Creating a new Instance are two very
> different things with very different use cases.
[quoted text clipped - 47 lines]
>>
>> Schneider
schneider - 03 Oct 2007 16:24 GMT
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

>I guess the problem with generics cloning comes from the possibility that a
><T> might not be cloneable.
[quoted text clipped - 61 lines]
>>>
>>> Schneider
Adrian Gallero - 04 Oct 2007 00:09 GMT
Hi,

> 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.

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,
  Adrian.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.