改进你的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/
改进你的c#代码的5个技巧(三)的更多相关文章
- 改进你的c#代码的5个技巧(四)
像每一篇文章一样,我会重复几行.我在我的Core i3 CPU.4GB主内存和Windows 7平台上测试了以下代码.如果你在不同的硬件配置或使用不同的平台,那么你的输出可能会随着我的输出屏幕而变化, ...
- 改进你的c#代码的5个技巧(一)
亲爱的读者,在这篇文章中,我提供了一些c#编程的最佳实践. 你是否在用户输入验证中使用异常处理机制? 如果是,那么你就是那个把你的项目执行速度降低了62倍的人.你不相信我吗?等几分钟;我来教你怎么做. ...
- 改进你的c#代码的5个技巧(二)
在本文中,我将向你展示c#编程的5个最佳实践.我从日常编程经验中学到了这些实践.我在release模式下测试了所有的代码,并在开发环境稳定后进行了截屏.我想你会喜欢这些建议的. 在使用数据类型之前选择 ...
- 以事实驳斥:改进你的c#代码的5个技巧(四)
测试使用的环境:vs2019+.net core3.1 原文地址:https://www.cnblogs.com/hhhnicvscs/p/14296715.html 反驳第一条:如何检查代码中的空字 ...
- Java 性能优化手册 — 提高 Java 代码性能的各种技巧
转载: Java 性能优化手册 - 提高 Java 代码性能的各种技巧 Java 6,7,8 中的 String.intern - 字符串池 这篇文章将要讨论 Java 6 中是如何实现 String ...
- Android中WebView的JavaScript代码和本地代码交互的三种方式
一.Android中WebView的漏洞分析最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视 ...
- PHP代码20个实用技巧(转)
这些技巧特别是封装的,相对路径的还是挺好的,本身来自微信公众号,但是我担心以后删除,所以在我的博客上备份一下(微信公众号为:菜鸟教程) 在这篇文章中我们将看看一些关于PHP开发有用的提示和技巧,可以用 ...
- php代码20个实用技巧 ------ 转发自菜鸟教程
1.不要实用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点:它首先查找指定的php包含路径,然后查找当前目录,因此会检查过 ...
- 写Java代码的一些小技巧
写Java代码有三年多了,遇到过很多坑,也有一些小小的心得.特地分享出来供各位学习交流.这些技巧主要涉及谷歌Guava工具类的使用.Java 8新特性的使用.DSL风格开发.代码封装等技巧. 一.nu ...
随机推荐
- 《Eroico》关卡与操作设计
操作设计: 没有给明操作教程,操作全靠蒙,只有改建的位置可以看到. 但游戏的难度并没有给玩家适应操作感,随着难度提升怪物血量增厚,但怪物并没有僵直英雄却有僵直.第一个小猫妖便给了玩家一个痛击. 方向键 ...
- GYM101889J Jumping frog
突然发现题刷累了写写题解还是满舒服的 题目大意: 给你一个只包含 \(R\) , \(P\) ,长度为 \(n\) 的字符串( \(3\le n\le 10^5\) ).你可以选择一个跳跃距离 \(l ...
- 动态规划之经典数学期望和概率DP
起因:在一场训练赛上.有这么一题没做出来. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6829 题目大意:有三个人,他们分别有\(X,Y,Z\)块钱 ...
- bbed工具安装
1.上传bbedus.msb bbedus.msg sbbdpt.o ssbbded.o四个文件到数据库服务器 [oracle@edgzrip1-PROD1 bbed_10g_src_x32]$ ...
- 面试 23-面试技巧 by smyhvae
23-面试技巧 by smyhvae #写简历的注意事项 最多可以写"深入了解",但不要写"精通". #遇到不知道的问题,该怎么回答 这块儿我没了解过,准备回去 ...
- 工作三年!全靠大佬的Java笔记,年底跳槽阿里涨了10K
前言 不论是校招还是社招都避免不了各种⾯试.笔试,如何去准备这些东⻄就显得格外重要,之前8月底阿里的人事部门打电话叫我要不要面试,当时正处于换工作的期间,于是就把简历发给阿里hr,人事审核后经过一些列 ...
- GDB —— 优化STL容器变量的显示
步骤 wget http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt cp dbinit_stl_views-1.03.txt ...
- 企业微信JS-SDK实现会话聊天功能
vue引入企业微信JS-SDK实现会话聊天功能 这两天在做一个对接企业微信实现会话聊天的功能, 发现企业微信文档这块儿做的不是特别详细,网上搜索也没找到特别完整的流程. 期间也踩了不少的坑, 在此进行 ...
- Python基础编程——数据类型
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 在程序设计和编程中,会涉及到各种各样的数据类型,而不同的数据类型变量之间可以进行的运算是不同的.在p ...
- 纯Python绘制艺术感满满的山脊地图,创意满分
1 简介 下面的这幅图是英国摇滚乐队 Joy Division 在1979年发行的其第一张录音室专辑 Unknown Pleasures 的封面,由艺术家 Peter Saville 基于射电脉冲星信 ...