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或者是附加到进程都是可以调试的。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackletter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值