关于c#:改进你的c代码的5个技巧三

3次阅读

共计 3904 个字符,预计需要花费 10 分钟才能阅读完成。

本文齐全独立于前两篇文章。如果你喜爱它们,我心愿你也会喜爱这个。在上一篇文章中,我展现了哪种办法更快,并比拟了代码的执行速度。在本文中,我将展现不同代码片段的内存耗费状况。为了显示内存映射和调配图,我应用了 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 块,程序能够无效地治理内存。

欢送关注我的公众号,如果你有喜爱的外文技术文章,能够通过公众号留言举荐给我。

正文完
 0