c#编程最佳实践:变量与方法

选择分配类数据成员的最佳方式

在为类变量赋值之前,我建议你现在查看以下代码和输出屏幕。

  •  
  •  
namespace Test{      public class Test      {          public staticstring Name { get; set; }        public staticString surname;    }    class Program    {        static void Main(string[] args)        {
            Stopwatch st = new Stopwatch();            st.Start();            for (int i = 0; i < 100; i++)            {                Test.Name = "Value";            }            st.Stop();            Console.WriteLine("Using Property: " + st.ElapsedTicks);            st.Restart();            for (int i = 0; i < 100; i++)            {                Test.surname = "Value";            }            st.Stop();            Console.WriteLine("Direct Assign: " + st.ElapsedTicks);            Console.ReadLine();        }    }  }

图片

 是的,我们的输出屏幕是说,使用属性分配数据成员比直接分配要慢得多。

 

 

不要使用new操作符来创建一个简单的整数变量。我知道你会说,如果你使用new操作符创建一个简单的整数变量就会被自动设置为0,不遭受错误,如“未赋值的局部变量”,但这真的是需要得到一个自动赋值为0,你的目的是创建一个局部变量来存储吗?让我们看看new操作符是如何降低代码执行的性能的。 

  •  
using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Diagnostics;  using System.IO;  using System.Net;  using System.Net.NetworkInformation;  namespace Test1  {      class Program      {          static void Main(string[] args)          {              Stopwatch sw = new Stopwatch();              sw.Start();              for (int i = 0; i < 1000; i++)              {                  int a = new int();                  a = 100;              }              sw.Stop();              Console.WriteLine("Using New operator:- " + sw.ElapsedTicks);              sw.Restart();              for (int i = 0; i < 1000; i++)              {                  int a;                  a = 100;              }              sw.Stop();              Console.WriteLine("Without new operator:- "+ sw.ElapsedTicks);              Console.ReadLine();          }      }  }

输出的截图如下:

图片

new操作符将执行速度降低了5倍。我可以否认输出屏幕,但有一件事!!你一次要创建1000个变量;在我们的项目中,我们不会一次创建1000个变量,最多创建2到3个。

好的。你的应用程序是web应用程序吗?如果是,那么请检查任何流行的web应用程序的点击数,我确信它超过1000每天。

同样,这一行的结论是“不要疯狂地使用new操作符来创建整数变量”。

04

05

方法是好的,但不是所有时候

如果你还记得你刚开始学习编程的那几天,你学过一个概念,就是总是实现一个方法来在代码中实现好的练习,是的,实现一个方法来执行某些任务是很好的。方法在编程中有成千上万的优点,但是让我们看看方法是如何降低执行性能的。我再次强调,这一点并不是反对方法,而是简单地展示方法调用是一种代价高昂的机制,并提供了在何处实现方法以及在何处不实现方法的想法。让我们看看下面的代码。

  •  
  •  
using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Diagnostics;  using System.IO;  using System.Net;  using System.Net.NetworkInformation;  namespace Test1  {      class test      {          public static void Print()          {              Console.WriteLine("I am function from Class");          }      }      class Program      {          static void Main(string[] args)          {              Stopwatch sw = new Stopwatch();              sw.Start();              test.Print();              sw.Stop();              Console.WriteLine(sw.ElapsedTicks);              sw.Restart();              Console.WriteLine("I am single statement within main");              sw.Stop();              Console.WriteLine(sw.ElapsedTicks);              Console.ReadLine();          }      }  }

下面是屏幕输出:

图片

在这里,我想在输出窗口中打印一条消息,首先,我在一个静态函数中实现了它,并通过类名调用它,第二次我只是在主函数中编写它。可以,通过Console.Writeline()非常简单。输出屏幕显示单行执行比函数快9倍。因此,唯一的结论是“在盲目执行某个功能之前,试着了解情况并做出最佳决策”

 

如果可能的话,使用静态函数

是的,如果可能的话,尝试实现一个静态函数,因为静态对象(函数和数据)不属于特定类的任何对象。这是大家都有的。因此,如果不创建对象,就不存在内存消耗的问题。下面我将展示一个静态函数和静态类的示例。看一下IL代码。

  •  
  •  
using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Diagnostics;  using System.IO;  using System.Net;  using System.Net.NetworkInformation;  using System.Threading;  using System.Globalization;  using System.Data.SqlClient;  namespace Test1  {      public static class mySclass      {          public static void Print()          {              Console.Write("Hello");          }      }      public class myNclass      {          public static void Print()          {              Console.Write("Hello");          }      }      class Program      {          static void Main(string[] args)          {              for (int i = 0; i < 1000; i++)              {                  mySclass.Print();                  myNclass.Print();              }          }      }  }

IL代码在左手边,在右手边是由CLR分析器获取的内存消耗类。由于空间消耗,我无法显示CLR分析器的完整截图。但是相信我,静态类或函数没有内存分配。

图片

因此,结论是“如果可能,尝试创建一个静态函数并使用类名调用,而不是通过对象名调用通用函数”。

 

空程序中哪个类消耗的资源最多?

首先,这一点并不推荐任何最佳实践技术。我只是想说明,如果我们运行一个空程序(其中只有一个Main()函数),那么分配了多少内存?下面是我的一个非常简单的程序。

  •  
  •  
using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;   namespace Test1  {      class Program      {          static void Main(string[] args)          {          }      }}

是的,我没有在这个程序里写任何东西。让我们看看内存映射。

图片

在这里,我展示了与运行空程序场景相关的六个最耗费资源的类。可以清楚地看到,String类占用了最多的资源(占全部资源的25%)。现在提问。在一个我们从不使用字符串的程序中,为什么字符串类消耗的资源最多?如果我们看一下这个程序的调用图,我们会看到在main函数中有许多内部函数被调用,它们中的大多数都以字符串作为参数,为了生成这些参数,CLR通常使用string类。如果你有不同的意见,请使用下面的评论框。

05

实现一个using块来管理内存

始终实现一个using块来管理资源是一个最佳实践。实际上,我们可以证明使用block语句比不使用block语句消耗的内存更少。我们知道,如果我们实现一个using块的块代码大小可能会更大,因为using块在内部在IL代码中创建了一个try catch,但一旦它在运行时在IL代码中实现,它就能有效地处理系统内存。为了演示这一点,我编写了一个简单的程序,如下所示:

  •  
  •  
using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Diagnostics;  using System.IO;  using System.Net;  using System.Net.NetworkInformation;  using System.Threading;  using System.Globalization;  using System.Data.SqlClient;  namespace Test1  {      class Test      {          public void Test1()          {               StreamWriter wr = new StreamWriter(@"D:\text.txt");          }          public void Test2()          {               using (StreamWriter wr = new StreamWriter(@"D:\abc.txt"))               {                }          }      }       class Program      {          static void Main(string[] args)          {              Test t = new Test();              t.Test1();              t.Test2();           }      }  }

在输出部分,我组合了三个输出屏幕。

图片

在分配图中,我们看到using块比没有using块时消耗的资源更少,因为如果我们实现了using块,程序可以有效地管理内存。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值