zoukankan      html  css  js  c++  java
  • 改进你的c#代码的5个技巧(三)

    本文完全独立于前两篇文章。如果你喜欢它们,我希望你也会喜欢这个。在上一篇文章中,我展示了哪种方法更快,并比较了代码的执行速度。在本文中,我将展示不同代码片段的内存消耗情况。为了显示内存映射和分配图,我使用了CLR profiler 32位版本,和往常一样,我在Windows平台上使用了4GB RAM和Core i3 CPU。内存消耗或分配图可能根据系统运行的进程而变化。因此,如果你得到一个不同的输出或行为的代码,那么请与我们分享你的经验。

    让我们开始“改进c#代码的5个技巧:第3部分”的旅程。

    StringBuilder消耗的内存比String少

    在我的上一篇文章中,我已经展示了在长连接操作的场景中字符串的速度有多慢。这里我们会看到一个字符串和StringBuilder的内存分配图。让我来演示一下。下面是我使用字符串和StringBuilder进行相同操作的代码。

    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 class Test1  
        {  
            string Name ;  
            public void Process()  
            {  
                Name = Name + "A";  
            }  
        }  
        public class Test2  
        {  
            StringBuilder sb = new StringBuilder();  
            public void Process()  
            {  
                sb.Append("A");  
            }  
        }  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                Test1 t = new Test1();  
                t.Process();   
                Test2 t1 = new Test2();  
                t1.Process();   
            }  
        }  
    }  

    这是代码执行时的内存分配图。

    这里我们从main函数调用两个函数Process();尽管它们都有相同的名称,但它们属于不同的类和Test1.Process处理字符串数据,而Test2.Process()处理StringBuilder数据。在分配图中,我们可以看到字符串处理函数消耗了Main()函数94%的资源,而Test2类中处理StringBuilder的Process()只消耗了Main()函数的0.21%的资源。

    因此,结论是“当你想多次连接字符串时,总是使用StringBuilder”。

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

    是的,如果可能的话,尝试实现一个静态函数,因为静态对象(函数和数据)不属于特定类的任何对象。这是大家都有的。因此,如果不创建对象,就不存在内存消耗的问题。下面我将展示一个静态函数和静态类的示例。看一下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分析器的完整截图。但是相信我,静态类或函数没有内存分配。

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

    字符串格式化VS字符串连接

    在第一点中,我展示了字符串如何比StringBuilder消耗更多的资源。在这一点上,我将比较格式化输出和字符串连接。在第一个函数中,我使用了一个格式规范来打印格式化的输出(基本上是连接一个字符串)。在另一个函数中,我使用(+)操作符连接一个字符串,如下所示:

    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 Format()  
            {  
                int a = 100;  
                Console.WriteLine("{0}AND{1}", a, a);  
            }  
            public void Concatination()  
            {  
                int a = 100;  
                Console.WriteLine(a + "AND" +a );  
            }  
        }   
        class Program  
        {  
            static void Main(string[] args)  
            {  
                Test t = new Test();  
                t.Format();  
                t.Concatination();  
                Console.ReadLine();  
            }  
        }  
    }  

    在内存分配中我们会看到:

    使用format打印字符串的函数消耗了57%的资源,而简单连接两个字符串的函数消耗了主函数的30%的资源。因此,我们可以清楚地看到,如果使用字符串连接而不是输出格式化,就可以节省系统资源。

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

    首先,这一点并不推荐任何最佳实践技术。我只是想说明,如果我们运行一个空程序(其中只有一个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类。如果你有不同的意见,请使用下面的评论框。

    实现一个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块,程序可以有效地管理内存。

    欢迎关注我的公众号,如果你有喜欢的外文技术文章,可以通过公众号留言推荐给我。

    原文链接:https://www.c-sharpcorner.com/UploadFile/dacca2/5-tips-to-improve-your-C-Sharp-code-part-2/

  • 相关阅读:
    PL/SQL编程急速上手
    MySQL编程
    T-SQL编程
    SQL入门,就这么简单
    前端工具配置(webpack 4、vue-cli 3)
    Vue-router
    Vue组件应用
    Vue.js应用基础
    Bootstrap应用核心
    一篇文章教会你jQuery应用
  • 原文地址:https://www.cnblogs.com/hhhnicvscs/p/14277905.html
Copyright © 2011-2022 走看看