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


    在本文中,我将向你展示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();
            }
        }  
    }  

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

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

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

  • 相关阅读:
    COGS 14. [网络流24题] 搭配飞行员
    洛谷 P3376 【模板】网络最大流
    洛谷 P2936 [USACO09JAN]全流Total Flow
    codevs 2038 香甜的黄油 USACO
    codevs 1993 草地排水 USACO
    Openjudge 2.5 6264:走出迷宫
    洛谷 P1744 采购特价商品
    HDU
    中国剩余定理
    bzoj2157: 旅游
  • 原文地址:https://www.cnblogs.com/hhhnicvscs/p/14239022.html
Copyright © 2020-2023  润新知