改进c# 代码的五个技巧(二)

在本文中,我将向你展示c#编程的5个最佳实践。我从日常编程经验中学到了这些实践。我在release模式下测试了所有的代码,并在开发环境稳定后进行了截屏。我想你会喜欢这些建议的。

在使用数据类型之前选择它

对于许多类型,我们宁愿不决定在日常编程生活中使用什么数据类型。就在几个月前,我也是其中之一。但是当我开始学习编程中的最佳实践以提高代码性能时,我了解到了错误的数据类型是如何影响代码的。我将展示一个演示来证明这个概念。

static void Main(string[] args)
{
  List<Int32> li = new List<int>();
  Stopwatch sw =new Stopwatch();
  sw.Start();
  for (int i = 0; i < 10000; i++)
  {
    li.Add(i);
  }
  sw.Stop();
  Console.Write("Using Arraylist(Object)" + sw.ElapsedTicks + "\n");
  sw.Reset();
  sw.Start();
  Int32[] a = new Int32[10000];
  for (int i = 0; i < 10000; i++)
  {
    a[i] = i;
  }
  sw.Stop();
  Console.Write("Using Value(Integer Array)" + sw.ElapsedTicks);
  Console.ReadLine();
}

在上面的代码中,首先我使用了一个list来存储1000个整数值,在第二次执行相同的操作时,我使用了一个整数数组。我的输出截图显示了哪种存储机制最适合整数数组。现在,你可能会想为什么这个list要花更多的时间呢?原因是,list以对象格式存储数据,当我们首先尝试存储值类型时,它将其转换为引用类型,然后再存储。因此,第一点是始终选择适当的存储机制以获得最佳性能。

使用for循环代替foreach

我现在要解释一个非常有趣的事实。我想你们都熟悉for和foreach循环。现在如果我问你哪个更快?嗯…不知道。对吧?

伙计们,for循环比foreach循环快得多。让我们看看下面的例子。

List<Int32> Count = new List<int>();
List<Int32> lst1 = new List<Int32>();
List<Int32> lst2 = new List<Int32>();

for (int i = 0; i < 10000; i++)
{
  Count.Add(i);
}

Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < Count.Count; i++)
{
  lst1.Add(i);
}
sw.Stop();

Console.Write("For Loop :- " + sw.ElapsedTicks + "\n");
sw.Restart();

foreach (int a in Count)
{
  lst2.Add(a);
}
sw.Stop();
Console.Write("Foreach Loop:- " + sw.ElapsedTicks);
Console.ReadLine();

不要担心,我已经在发布模式下测试了这个示例,这个屏幕截图是在几次测试运行后拍摄的。

选择何时使用类,何时使用结构体

接受这样一个事实,即基本理解了c#中的结构体和类,或者至少理解了最喜欢的编程语言中的结构体和类(如果它们存在的话)。好吧,如果你在想“很久以前我学过结构体,但在日常编码生活中从未使用过它”,那么你就是那95%从未测量过类和结构体性能的开发人员中的一员。别担心;在写这篇文章之前,我也没有。

那么类呢?是的,我们时不时地在日常项目开发中实现一个类。

现在我的问题是“哪个更快,类还是结构体”?我猜你会想“从未测试过”。好的,我们来测试一下。看看下面的代码。

namespace BlogProject
{
  struct MyStructure
  {
    public string Name;
    public string Surname;
  }
  class MyClass
  {
    public string Name;
    public string Surname;
  }
  class Program
  {
    static void Main(string[] args)
    {

      MyStructure[] objStruct = new MyStructure[1000];
      MyClass[] objClass = new MyClass[1000];

      Stopwatch sw = new Stopwatch();
      sw.Start();
      for (int i = 0; i < 1000; i++)
      {
        objStruct[i] = newMyStructure();
        objStruct[i].Name = "Sourav";
        objStruct[i].Surname = "Kayal";
      }
      sw.Stop();
      Console.WriteLine("For Structure:- " + sw.ElapsedTicks);
      sw.Restart();

      for (int i = 0; i < 1000; i++)
      {
        objClass[i] = newMyClass();
        objClass[i].Name = "Sourav";
        objClass[i].Surname = "Kayal";
      }
      sw.Stop();
      Console.WriteLine("For Class:- " + sw.ElapsedTicks);

      Console.ReadLine();
    }
  }
}

输出结果如下:

现在很明显,结构体要比类快得多。同样,我在发布模式下测试了这段代码,并获得了至少20个输出,以使程序达到稳定的位置。

现在最大的问题是“为什么结构体比类快?”

正如我们所知,结构体变量是值类型,值(或结构体变量)存储在一个位置。

类对象是引用类型。如果是对象类型,则创建引用,并将值存储在内存的其他位置。基本上,值存储在一个可管理的堆中,指针创建在堆栈中。以这种方式在内存中实现一个对象,通常要比结构体变量花费更多的时间。

始终使用Stringbuilder进行字符串连接操作

这一点对开发人员来说非常关键。在进行大量字符串拼接操作时,请使用StringBuilder代替String。为了演示它对代码性能的影响,我准备了以下示例代码。我在for循环中执行了500次字符串拼接操作。

public classTest
{
  public static string Name { get; set; }
  public static string surname;
}
class Program
{
  static void Main(string[] args)
  {
    string First = "A";
    StringBuilder sb = new StringBuilder("A");

    Stopwatch st = new Stopwatch();
    st.Start();
    for (int i = 0; i < 500; i++)
    {
      First = First + "A";
    }
    st.Stop();
    Console.WriteLine("Using String :-" + st.ElapsedTicks);
    st.Restart();

    for (int i = 0; i < 500; i++)
    {
      sb.Append("A");
    }
    st.Stop();
    Console.WriteLine("Using Stringbuilder :-" + st.ElapsedTicks);
    Console.ReadLine();
  }
}

这是输出:

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

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

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();
    }
  }
}

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

以上就是改进c# 代码的五个技巧(二)的详细内容,更多关于改进c# 代码的资料请关注我们其它相关文章!

(0)

相关推荐

  • SQLite在C#中的安装与操作技巧

    SQLite 介绍 SQLite,是一款轻型的数据库,用于本地的数据储存. 先说说优点,它占用资源非常的低,在嵌入式设备中需要几百K的内存就够了:作为轻量级数据库,他的处理速度也足够快:支持的的容量级别为T级:独立: 没有额外依赖:开源:支持多种语言: 我的用途 在项目开发中,需要做一次数据数据同步.因为数据库实时数据的同步,需要记录更新时间,系统日志等等数据:当然,你也可以选择写ini和xml等等配置文件来解决,但是都如数据库可读性高不是. 安装 1. 引用 .NET 驱动 http://sy

  • C#中如何为枚举类型添加描述方法【小技巧】

    背景 在我们的日常开发中,我们会经常使用枚举类型.枚举类型(enum type)是具有一组命名常量的独特的值类型.在以下示例中: enum Color { Red, Green, Blue } 声明一个名为 Color 的枚举类型,该类型具有三个成员:Red.Green 和 Blue. 枚举具体是怎么声明呢?枚举声明用于声明新的枚举类型.枚举声明以关键字 enum 开始,然后定义该枚举类型的名称.可访问性.基础类型和成员.具体格式: 修饰词(new.public.protected.intern

  • C# WinForm快捷键设置技巧

    1.Alt+*(按钮快捷键) 按钮快捷键也为最常用快捷键,其设置也故为简单.在大家给button.label.menuStrip等其他控件的Text属性指定名称时,在其后面加上'&'然后在加上一个指定字母即可.如:确定(&D),(Alt+D)调用. 如指定多个字母,则第一个为快捷键.如:确定(&OK),(Alt+O)调用;文件(&Fill),(Alt+F)调用. 2.Ctrl+*及其他组合键 把 Form 的 KeyPreview 属性设为 True 使用Modifiers

  • c# 代码调试技巧和如何远程调试

    一:背景 1. 讲故事 每次项目预交付的时候,总会遇到各种奇葩的坑,我觉得有必要梳理一下以及如何快速解决的,让后来人避避坑,这篇就聊聊自己的所闻所遇: 我去,本地环境代码跑的哧溜,上了测试环境出问题 我去, 第三方提供的 dll 跑出 bug 了 二:两个大坑的解决方案 1. 本地环境没问题,上了测试出问题 相信很多朋友都有我这样类似的遭遇,明明程序代码,配置文件都一样,挪了一个窝就出问题,你说气人不,既然问题出了那怎么快速解决呢? 对,就是用调试,但程序部署在 centos 上,送一个 vis

  • C#异常处理的技巧和方法

    c#中或多或少回出现一些意向不道的异常,那么如何去捕获这个异常就非常的关键--这个异常可能是系统的不可控因素也有可能是程序本身才一个异常.下面就具体的解决方案提供给大家,希望有所帮助 从最常见的分母为0的情况的实例 通过try catch finally三个关键字的一个语法结构图.finally是监听程序是否在try或者catch中执行 下面列举的是try执行的语句是一个异常错误的情况 下面列举的是try执行语句是一个正确的情况 异常类的一个继承顺序图,异常类中的属性列表 catch中的表达式的

  • 在C#及.NET框架中使用StringBuilder类操作字符串的技巧

    但如果性能的优劣很重要,则应该总是使用 StringBuilder 类来串联字符串.下面的代码使用 StringBuilder 类的 Append 方法来串联字符串,因此不会有 + 运算符的链接作用产生. class StringBuilderTest { static void Main() { string text = null; // Use StringBuilder for concatenation in tight loops. System.Text.StringBuilder

  • c# Linq常用的小技巧

    前言 在C#语言发展的历史长河中,Linq是一个极其重要的里程碑! Linq的语法吸取了SQL语法的特性,同时配合Lambda表达式又可以使代码更加优雅! 可以这么说,用好了Linq可以大大提高程序猿的工作效率,毕竟我们的日常工作本质就是对数据的处理.经历了十多年的发展,现在微软自带的内库包含的Linq函数已经非常多了,几乎满足我们日常工作. 下面根据一个对科室数据操作的例子,就个人觉得日常高频使用的Linq小技巧贴出来,权当是做个笔记了. 初始化数据 定义模型 这里定义一个科室对象,模拟我们日

  • C#中使用Interlocked进行原子操作的技巧

    什么是原子操作? 原子(atom)本意是"不能被进一步分割的最小粒子",而原子操作(atomic operation)意为"不可被中断的一个或一系列操作" .在C#中有多个线程同时对某个变量进行操作的时候,我们应该使用原子操作,防止多线程取到的值不是最新的值. 例如:int result = 0; 多线程A正在执行 result(0)+1 多线程B同时执行 result(0)+1 那么最终result的结果是1还是2呢,这个就很难说了.如果在CPU中2个线程同时计算

  • 改进c# 代码的五个技巧(一)

    亲爱的读者,在这篇文章中,我提供了一些c#编程的最佳实践. 你是否在用户输入验证中使用异常处理机制? 如果是,那么你就是那个把你的项目执行速度降低了62倍的人.你不相信我吗?等几分钟;我来教你怎么做.但是在这个例子之前,让我们了解一下在什么地方需要异常处理. 例如,你正在验证用户的数据,对于任何无效的输入,你将引发一个异常并将其抛出给客户端,如下所示: class BusinessLogcCheck { public void Check() { try { //Your validation

  • 改进c# 代码的五个技巧(二)

    在本文中,我将向你展示c#编程的5个最佳实践.我从日常编程经验中学到了这些实践.我在release模式下测试了所有的代码,并在开发环境稳定后进行了截屏.我想你会喜欢这些建议的. 在使用数据类型之前选择它 对于许多类型,我们宁愿不决定在日常编程生活中使用什么数据类型.就在几个月前,我也是其中之一.但是当我开始学习编程中的最佳实践以提高代码性能时,我了解到了错误的数据类型是如何影响代码的.我将展示一个演示来证明这个概念. static void Main(string[] args) { List<

  • 值得收藏的9个提高代码运行效率的小技巧(推荐)

    我们写程序的目的就是使它在任何情况下都可以稳定工作.一个运行的很快但是结果错误的程序并没有任何用处.在程序开发和优化的过程中,我们必须考虑代码使用的方式,以及影响它的关键因素.通常,我们必须在程序的简洁性与它的运行速度之间做出权衡.今天我们就来聊一聊如何优化程序的性能. 1. 减小程序计算量 1.1 示例代码 for (i = 0; i < n; i++) { int ni = n*i; for (j = 0; j < n; j++) a[ni + j] = b[j]; } 1.2 分析代码

  • JavaScript 七大技巧(二)

    上篇文章给大家介绍了JavaScript 七大技巧(二),写JavaScript代码已经很久了,都记不起是什么年代开始的了.对于JavaScript这种语言近几年所取得的成就,我感到非常的兴奋;我很幸运也是这些成就的获益者.我写了不少的文章,章节,还有一本专门讨论它的书,然而,我现在依然能发现一些关于这种语言的新知识.下面的描述的就是过去让我不由得发出"啊!"的感叹的编程技巧,这些技巧你应该现在就试试,而不是等着未来的某个时候偶然的发现它们. var band = { "na

  • 分享10提高 Python 代码的可读性的技巧

    目录 1.字符串反转 2.首字母大写 3.查询唯一元素 4.变量交换 5.列表排序 6.列表推导式 7.合并字符串 8.拆分字符串 9.回文串检测 10.统计列表元素出现次数 1. 字符串反转 字符串反转有很多方法,咱们再这里介绍两种:一种是切片,一种是python字符串的reversed方法. # -!- coding: utf-8 -!- string = 'hello world' # 方法1 new_str = string[::-1] ic(new_str) # 方法二 new_str

  • JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)

    在上篇文章给大家介绍了JavaScript实现跑马灯抽奖活动实例代码解析与优化(一),既然是要编写插件.那么叫做"插件"的东西肯定是具有的某些特征能够满足我们平时开发的需求或者是提高我们的开发效率.那么叫做插件的东西应该具有哪些基本特征呢?让我们来总结一下: 1.JavaScript 插件一些基本特征: 配置一定要简单 插件中定义的变量不污染全局变量: 同一段代码可以在不同的地方复用: 用户可以自定义自己功能参数: 具有销毁变量和参数的功能: 如果按照以上的几个特征来写插件的话,我们可

  • 如何改进javascript代码的性能

    本来在那片编写可维护性代码文章后就要总结这篇代码性能文章的,耽搁了几天,本来也是决定每天都要更新一篇文章的,因为以前欠下太多东西没总结,学过的东西没去总结真的很快就忘记了,记录一下在你脑力留下更深的印象,特别是这些可维护性代码,性能什么的,当在你脑子里形成一种习惯了,那你就牛了!这里也要给初学者一个建议:多总结你学过的东西,因为这其实也是在学习新知识! 好,进入我们的主题:如何提高JS代码的性能. 1.优化DOM交互 DOM与我们的页面紧密相关,浏览器渲染页面也就是在渲染解析后的DOM元素,DO

  • Java代码实践12306售票算法(二)

    周五闲来无事,基于上一篇关于浅析12306售票算法(java版)理论,进行了java编码实践供各位读者参考(以下为相关代码的简单描述) 1.订票工具类 1.1初始化一列车厢的票据信息 /** * 生成Ticket信息 * * @param train * @return */ public static List<Ticket> initTicketList(Train train) { List<Ticket> result = new ArrayList<Ticket&g

  • 一些让Python代码简洁的实用技巧总结

    目录 前言 1. 使用Lambda来修改Pandas数据框中的值 2. 使用f-string来连接字符串 3. 用Zip()函数对多个列表进行迭代 4. 使用列表理解法 5. 对文件对象使用with语句 6. 停止使用方括号来获取字典项, 利用.get()代替 7. 多重赋值 总结 前言 众所周知,编写Python代码在开始时十分容易,但随着你在工具包中添加更多的库,你的脚本可能会有不必要的代码行,变得冗长而混乱.可能短期内能够应付工作,但长期来看,麻烦不小. 在这篇文章中,我将与你分享7个技巧

  • JavaScript 数组常见操作技巧 (二)

    目录 一.出数组中的重复元素或非重复元素 二.数组扁平化 / 数组降维 二维数组:双重循环 二维数组:循环 + concat 二维数组:reduce + concat 二维数组:展开 / apply + concat 多维数组:toString + split 多维数组:forEach + 递归 多维数组:reduce + 递归 多维数组:while + some 不确定维数的数组: flat 前言: 数组是 JavaScript 中常见数据类型之一,关于它的一些操作方法,我在这里做一下简单记录

随机推荐