日志

改进你的c#代码的5个技巧(三)

 来源    2021-01-14    1  

本文完全独立于前两篇文章。如果你喜欢它们,我希望你也会喜欢这个。在上一篇文章中,我展示了哪种方法更快,并比较了代码的执行速度。在本文中,我将展示不同代码片段的内存消耗情况。为了显示内存映射和分配图,我使用了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/

相关文章
语言无关 – 阅读其他人代码所需的技巧或必需技能
问答目前我已经开始了非常大的遗产项目,并且我一直担心阅读和理解其他人的代码,我知道这是一项必不可少的技能,但是直到不需要它才开发出来.现在它就像发展这项技能而不是业余爱好一样,所以我想从SO读者那里了解: ...
1
优化 – 将SSE(SSSE3)YUV改进为RGB代码
问答我正在寻找优化我写的用于将YUV转换为RGB(平面和打包YUV函数)的一些SSE代码. 我目前正在使用SSSE3,但如果后来的SSE版本中有一些有用的功能可以. 我主要对如何处理处理器档位等感兴趣. ...
3
改进我的代码以折叠data.frames列表
问答亲爱的StackOverFlowers(花简), 我有一个data.frames(walk.sample)列表,我想将其合并为一个(巨型)data.frame.在折叠时,我想标记(添加另一列)哪些行来 ...
1
c# – 我现在如何改进这个价格计算代码进行4次计算,但是在不久的将来会有更多?
问答我正在努力研究如何改进我编写的一些代码,这些代码使用一些规则来计算汽车保险的几个不同的价格.这是困扰我的作品: public Insurance GetInsurance(CarData carDat ...
1
c# – 如何改进此排序代码?
问答我正在检查sort参数并构建一堆if语句: if (sortDirection == "ASC") { if (sortBy == "Id") return c ...
3
c# – .NET字符串解析性能改进 – 可能的代码嗅觉
问答下面的代码旨在获取一个字符串并删除任何被认为对搜索短语不重要的任意单词. 我没有编写代码,但需要将其合并到其他内容中.它有效,这很好,但我感觉不对.但是,我似乎无法理解这种方法已经创造出来考虑另一种方 ...
1
string – “fasta文件中序列的平均长度”:你能改进这个Erlang代码吗?
问答我试图使用Erlang获得平均长度fasta sequences. fasta文件看起来像这样 >title1 ATGACTAGCTAGCAGCGATCGACCGTCGTACGC ATCGATC ...
1
如何改进我的程序设计和解决问题的技巧?
问答我现在已经编码了一段时间,并且可以使用几种编程语言进行编码,但现在觉得我需要改进我的问题解决或程序设计技术. 我需要什么技能才能设计一个程序来解决问题? 更多: 问题在于如何设计一个解决方案,而不是如 ...
1
语言无关 – 改进我们编写代码的方式?
问答在考虑软件工程的时候,我遇到了一个问题,为什么我们在写/文档代码方面看不到任何改进. 想想:自从我们从打卡转到文本编辑以来,还没有一个革命性的改进.我看到的最后一个改进是语法高亮和上下文相关帮助(例如 ...
1
ruby-on-rails – 如何改进此Rails代码?
问答我正在编写一个小浏览器游戏作为学习RoR的项目,我对它很陌生. 这是一个由cronjob定期调用的方法. 我猜应该有一些方法可以在魔药阵列中添加元素,然后在最后进行批量保存,我也不喜欢每次在循环中点击 ...
1
你能改进这个C#正则表达式代码吗?
问答在一个程序中,我正在读取一些数据文件,其中一部分格式化为一系列记录,每个记录都放在方括号中.每条记录都包含一个节标题和一系列键/值对. 我最初编写代码来循环并提取值,但决定使用正则表达式可以更优雅地完 ...
1
如何改进这个Java代码来查找字符串中的子字符串?
问答最近我被要求提交解决问题的办法. 问题:在字符串中查找一个子字符串. Input: "Little star's deep dish pizza sure is fantastic.&quo ...
2
改进我的R代码以计算数据帧的Z分数
问答我的任务是生成一个R代码,用于计算Z分数,然后将其输出到文件.虽然脚本有效,但我对一些令我困惑的行提出了一些问题. INPUT.TXT: GeneID GeneID-2 GeneName TSS-ID ...
1
递归 – 如何改进这段代码?
问答我对SICP exercise 1.11的解决方案是: (define (f n) (if (< n 3) n (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f ...
1
javascript – 如何改进我的代码以实现’return false’?
问答我试图在条件语句失败后返回false. 我有 $('#btn').click(function() { $('.title').each(function() { if (id == $(this). ...
1
改善代码可测性的若干技巧
日志概述 软件的工程性体现在质量与效率.单测是构成软件质量的第一道防线,而单测覆盖率是软件质量的重要指标之一. 编写容易测试的代码,可带来更佳的单测覆盖率,间接提升开发效率. 为什么程序员不大写单测呢? ...
1
写出优质Java代码的4个技巧
日志我们平时的编程任务不外乎就是将相同的技术套件应用到不同的项目中去,对于大多数情况来说,这些技术都是可以满足目标的.然而,有的项目可能需要用到一些特别的技术,因此工程师们得深入研究,去寻找那些最简单但最 ...
1
30段极简Python代码:这些小技巧你都Get了么
日志学 Python 怎样才最快,当然是实战各种小项目,只有自己去想与写,才记得住规则.本文是 30 个极简任务,初学者可以尝试着自己实现:本文同样也是 30 段代码,Python 开发者也可以看看是不是 ...
2
Python 代码使用pdb调试技巧
日志Debug 对于任何开发人员都是一项非常重要的技能,它能够帮助我们准确的定位错误,发现程序中的 bug.python 提供了一系列 debug 的工具和包,可供我们选择.本文将主要阐述如何利用 pyt ...
1
Java 性能优化手册 — 提高 Java 代码性能的各种技巧
日志转载: Java 性能优化手册 - 提高 Java 代码性能的各种技巧 Java 6,7,8 中的 String.intern - 字符串池 这篇文章将要讨论 Java 6 中是如何实现 String ...
1