我是靠谱客的博主 标致宝贝,最近开发中收集的这篇文章主要介绍c#中Debug和Release的区别实验,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

环境:

  • window 10
  • vs 2019 16.4.5
  • .netcore 3.1.1

参照:
项目发布Debug和Release版的区别
享受release版本发布的好处的同时也应该警惕release可能给你引入一些莫名其妙的大bug

一、Releas版本相比Debug版本的性能提升很大

Debug模式在编译时不对源代码进行优化,而Release模式进行了大胆的优化,使得程序在代码大小和运行速度上都有显著提高。
下面通过一个对10000条数据进行冒泡排序的例子来比较它们二者的性能差距:

class Program
{
    public static void Main(string[] args)
    {
        //准备测试数据
        var len = 10000;
        var datas = new int[len];
        for (int i = 0; i < len; i++)
        {
            datas[i] = new Random().Next(1, 100000);
        }
        //冒泡排序5次
        for (int i = 0; i < 5; i++)
        {
            var arr = new int[datas.Length];
            datas.CopyTo(arr, 0);
            Stopwatch watch = new Stopwatch();
            watch.Start();
            Order(arr);
            watch.Stop();
            Console.WriteLine(watch.Elapsed);
        }
        Console.WriteLine("ok");
        Console.Read();
    }

    public static int[] Order(int[] datas)
    {
        for (int i = 0; i < datas.Length; i++)
        {
            for (int j = i + 1; j < datas.Length; j++)
            {
                if (datas[i] < datas[j])
                {
                    int t = datas[i];
                    datas[i] = datas[j];
                    datas[j] = t;
                }
            }
        }
        return datas;
    }
}

Debug模式的输出:
在这里插入图片描述
Release模式的输出:
在这里插入图片描述
从上满可以看到,将近三倍的性能差距!!!

二、Releas版本可能会出现莫名的bug

虽然通过上面的对比可以看到Releas版本有着较大的性能优势,但同时它也可能带来了莫名的bug。上面说到,编译器对代码进行了大胆的优化,比如说将一些值直接读取到cpu高速缓存中,这在多线程的操作环境中就可能带来问题,下面看一个例子:

class Program
 {
     static int isStop = 0;
     public static void Main()
     {
         var t = new Thread(() =>
         {
             var isSuccess = true;
             while (isStop == 0)
             {
                 isSuccess = !isSuccess;
             }
         });
         t.Start();
         Thread.Sleep(1000);
         isStop = 1;
         t.Join();
         Console.WriteLine("ok");
         Console.ReadLine();
     }
 }

Debug版本的输出:
在这里插入图片描述
Release版本的输出:
在这里插入图片描述
可以看到,Release版本没有输出,说明它死循环了没有读取到isStop 的改变值,这其实就是Release版本的优化导致的。Releas版本把isStop缓存到了CPU的告诉缓存中,导致主线程修改了isStop的值却不能反馈到新线程上去。

那么有没有解决办法呢?

  • 办法1:不要在多线程中这么操作变量。
  • 办法2:不要使用Releas版本
  • 办法3:使用MemoryBarrier/VolatileRead
  • 办法4:使用volatile 关键字

其实,真正解决问题的就是办法3和办法4,那么我们看看这两个是什么东西:

  • VolatileRead:忽略CPU的高速缓存,获取最新的数据,这句话执行后就会将isStop刷新,从下面的注释中也可以看得出来
    在这里插入图片描述
    上面的代码使用Release编译后发现是正常的了。
  • MemoryBarrier:参照:MemoryBarrier方法
    在这里插入图片描述
    使用上面的代码处理后,Release再编译也正常了。
  • volatile关键字
    这个关键字要用在类的字段上,如下所示:
    在这里插入图片描述
    这样使用Release编译后也正常了。

三、Release版本的调试问题

在调试中去掉"仅我的代码“即可!
在这里插入图片描述
这样,无论你是F5或者是附加到进程都是可以调试的。

最后

以上就是标致宝贝为你收集整理的c#中Debug和Release的区别实验的全部内容,希望文章能够帮你解决c#中Debug和Release的区别实验所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部