c#release与debug性能差异_delphi反编译工具

c#release与debug性能差异_delphi反编译工具环境:window10vs201916.4.5.netcore3.1.1参照:项目发布Debug和Release版的区别一、Releas版本相比Debug版本的性能提升很大Debug模式在编译时

环境:

  • 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#release与debug性能差异_delphi反编译工具分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/85407.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注