• C# 代码性能优化举例 野峰


    普通人如果说什么事情慢,指的是 5 分钟,10 分钟,或者 1 个小时、2 个小时。而程序员要说什么事情慢,他们指的是 2 纳秒。

    每个纳秒对程序员来说都是非常宝贵的,所以,要对代码进行优化,优化,再优化,每个纳秒都不要浪费。

    在 C# 程序中,完成一件任务通常都有若干种方法,但这些方法之间是存在一些差异的,特别是性能上的差异。本文尝试着举几个例子来说明这种差异。

    1. 装箱还是不装箱(to box or not to box)

    一般来说,值类型的数据都是在栈上操作的,而引用类型的数据都是在堆上的,而当值类型需要作为引用类型操作时,都要先对值类型数据进行装箱,使其变为引用类型。但装箱操作是一个成本很高的操作,要尽量避免使用。如对于如下代码:

    static string GetArrayInfo(Array a)
    {
        string s = $"An array with {a.Length} elements.";
        return s;
    }

    其中,a.Length 是一个整型的值类型变量,与字符串混合在一起时,需要进行装箱操作。可改为如下代码以避免装箱操作:

    static string GetArrayInfo(Array a)
    {
        string s = "An array with " + a.Length.ToString() + " elements.";
        return s;
    }

    2. 构造字符串(building strings) 

    构造字符串,可以使用 StringBuilder,也可以直接用 + 操作符(编译为对 Concat() 方法的调用)连接字符串。一般来说,使用 StringBuilder 是一种高性能的字符串构造方案,但也不尽然,尤其是 StringBuilder 的 AppendFormat() 方法,成本很高,应尽量避免使用。举例如下。

    static string Greeting(string name)
    {
        StringBuilder sb = new();
        _ = sb.AppendFormat("Hello, {0}", name ?? "null");
        return sb.ToString();
    }

    下面的代码使用 Append() 方法构造字符串:

    static string Greeting(string name)
    {
        StringBuilder sb = new();
        _ = sb.Append("Hello, ");
        _ = sb.Append(name ?? "null");
        return sb.ToString();
    }

    最后,我们用 + 操作符(Concat() 方法)构造同样的字符串:

    static string Greeting(string name)
    {
        return "Hello, " + name ?? "null";
    }

    经过实测,+ 操作符方法(Concat() 方法)性能最好,StringBuilder 的 Append() 次之,AppendFormat() 最差。

    3. 类型转换(type conversion)

    如将一个数字字符串转换为整型数,一般有三种方法实现转换:

    // 方法1:
    _ = int.TryParse("123", out int n);
    
    // 方法2:
    int n = int.Parse("123");
    
    // 方法3:
    int n = Convert.ToInt32("123");

    这三种方法都可以。从安全性上讲,int.TryParse() 最安全,从性能上说,则 Convert.ToInt32() 最好(但也相差不大)。如果能确定输入字符串的合法性,则尽量使用 Convert.ToInt32() 方法,反之,则使用 int.TryParse() 以避免抛出异常。

    以上三个实例的实测数据如下图所示,这是经过 100 次循环,每次循环执行 1000000 次调用,经过平均后得出的结果。

    提高程序的运行性能,除了选用高性能的硬件(高性能CPU、内存、硬盘等)之外,在软件上也要下功夫进行优化。优化涉及的方面很多,代码优化是其中很重要的环节。本文从“黑盒”角度举了几个例子并进行实际测试,以揭示不同方法的实现性能。

  • 相关阅读:
    nginx+uWSGI+django+virtualenv+supervisor发布web服务器
    Nginx负载均衡
    python操作 redis
    Python之Linux下的 virtualenv
    python习题:写一个函数-校验字符串是否为合法的小数
    python习题:修改文件里的内容
    python习题:如果同一个ip地址60s之内访问超过200次,那么就把这个ip地址加入黑名单
    python自动化测试-D4-学习笔记之三(函数)
    python自动化测试-D4-学习笔记之二(集合)
    python自动化测试-D4-学习笔记之一(文件读写补充)
  • 原文地址:https://www.cnblogs.com/prowyh/p/15828422.html
Copyright © 2020-2023  润新知