new与clone的比较

  简单来说,new仅申请开辟内存,而后调用类的构造函数来初始化对象。clone也是先开辟内存,但不会调用构造函数来初始化,而是将源对象值复制给目标对象。若是深拷贝,则还需要一同拷贝源对象引用类型指向的内存,浅拷贝则只是拷贝引用本身。

  如下小示例:

 1     /// <summary>
 2     /// 围棋子(棋盘共19×19=361个交叉点,对象可能有三百多个)
 3     /// </summary>
 4     [Serializable]
 5     public class PiecesGo : ICloneable
 6     {
 7         /// <summary>
 8         /// 棋子颜色(Black、White)
 9         /// </summary>
10         public string Color { get; set; }
11 
12         /// <summary>
13         /// 棋子位置(X)
14         /// </summary>
15         public int PointX { get; set; }
16 
17         /// <summary>
18         /// 棋子位置(Y)
19         /// </summary>
20         public int PointY { get; set; }
21 
22         /// <summary>
23         /// 构造棋子
24         /// </summary>
25         /// <param name="color">颜色:Black、White</param>
26         /// <param name="x">X坐标</param>
27         /// <param name="y">Y坐标</param>
28         public PiecesGo(string color, int x, int y)
29         {
30             //Guid.NewGuid().ToString();
31             Color = color;
32             PointX = x;
33             PointY = y;
34         }
35 
36         /// <summary>
37         /// 创建当前object的浅表副本
38         /// 返回Object
39         /// </summary>
40         /// <returns>object</returns>
41         public object Clone()
42         {
43             return base.MemberwiseClone();
44         }
45 
46         /// <summary>
47         /// 浅拷贝
48         /// 返回PiecesGo
49         /// </summary>
50         /// <returns>PiecesGo</returns>
51         public PiecesGo ShallowClone()
52         {
53             return this.Clone() as PiecesGo;
54         }
55 
56         /// <summary>
57         /// 深拷贝
58         /// 返回PiecesGo
59         /// </summary>
60         /// <returns></returns>
61         public PiecesGo DeepClone()
62         {
63             using (Stream objectStream = new MemoryStream())
64             {
65                 IFormatter formatter = new BinaryFormatter();
66                 formatter.Serialize(objectStream, this);
67                 objectStream.Seek(0, SeekOrigin.Begin);
68                 return formatter.Deserialize(objectStream) as PiecesGo;
69             }
70         }
71     }
 1     /// <summary>
 2     /// 1.new与clone的性能差别主要在构造函数和对象包含的引用(浅拷贝可忽略);
 3     /// 2.若构造函数功能简单,则new耗时更少;
 4     /// 3.若构造函数比较耗时,则clone(浅)耗时更少(克隆不用走构造);
 5     /// 4.无论两者情况如何,深拷贝耗时都是最多的。
 6     /// </summary>
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             int cnt = 100000;
12 
13             //New
14             DateTime dt1 = DateTime.Now;
15             for (int i = 0; i < cnt; i++)
16             {
17                 PiecesGo go = new PiecesGo("black", i, i);
18             }
19             DateTime dt2 = DateTime.Now;
20             Console.WriteLine("New:" + (dt2 - dt1).TotalMilliseconds);
21 
22             //ShallowClone
23             DateTime dt3 = DateTime.Now;
24             PiecesGo pieces = new PiecesGo("black", 0, 0);
25             for (int i = 0; i < cnt; i++)
26             {
27                 PiecesGo go = pieces.ShallowClone();
28                 go.Color = "white";
29                 go.PointX = i;
30                 go.PointY = i;
31             }
32             DateTime dt4 = DateTime.Now;
33             Console.WriteLine("ShallowClone:" + (dt4 - dt3).TotalMilliseconds);
34 
35             //DeepClone
36             DateTime dt5 = DateTime.Now;
37             PiecesGo pieces2 = new PiecesGo("black", 0, 0);
38             for (int i = 0; i < cnt; i++)
39             {
40                 PiecesGo go = pieces2.DeepClone();
41                 go.Color = "black";
42                 go.PointX = i;
43                 go.PointY = i;
44             }
45             DateTime dt6 = DateTime.Now;
46             Console.WriteLine("DeepClone:" + (dt6 - dt5).TotalMilliseconds);
47 
48             //NewGuidToString
49             DateTime dt7 = DateTime.Now;
50             for (int i = 0; i < cnt; i++)
51             {
52                 Guid.NewGuid().ToString();
53             }
54             DateTime dt8 = DateTime.Now;
55             Console.WriteLine("NewGuidToString:" + (dt8 - dt7).TotalMilliseconds);
56 
57             //NewGuid
58             DateTime dt9 = DateTime.Now;
59             for (int i = 0; i < cnt; i++)
60             {
61                 Guid.NewGuid();
62             }
63             DateTime dt10 = DateTime.Now;
64             Console.WriteLine("NewGuid:" + (dt10 - dt9).TotalMilliseconds);
65 
66             Console.Read();
67         }
68     }

  1.new与clone的性能差别主要在构造函数和对象包含的引用(浅拷贝可忽略);
  2.若构造函数功能简单,则new耗时更少;
  3.若构造函数比较耗时,则clone(浅)耗时更少(克隆不用走构造);
  4.无论两者情况如何,大部分情况下深拷贝耗时都是最多的。

posted on 2019-05-30 17:24  庭前花满留晚照  阅读(1100)  评论(0)    收藏  举报

导航