zoukankan      html  css  js  c++  java
  • 提高一下dotnet程序的效率一

     

    异常机制

    一直以来,有个想法,就是依靠异常机制传递一些信息。如果软件分了层次,或者模块间传递信息,如果采用返回值,就需要定义这些值的含义。例如1代表什么,2代表什么,好一点的话用枚举类型。后来看到有人采用throw机制来传递用户输入的登录凭据不对什么的,就有了一个错误提示信息在层间传递的想法。故而进行一个测试。

    protected void Page_Load(object sender, EventArgs e)

            {

                DateTime t = DateTime.Now;

                try

                {

                    try

                    {

                        TestExption();

                    }

                    catch(Exception x)

                    {

                        throw x;

                    }

                }

                catch { }

                DateTime t1 = DateTime.Now;

                Response.Write((t1 - t).TotalMilliseconds);

            }

            protected bool TestExption()

            {

                throw new Exception("ddd");

                return false;

        }

    以上测试的结果是,在我的机器:intel duo T7500 2GB内存的配置下,最终得到30多毫秒的结果。

    如果没有外面一个try…catch…块,那么得到15多毫秒的结果。

    如果去掉throw语句,无论有没有try…catch…,有一个还是两个,得到的都是0毫秒。

    看来一个try…catch…块的开销是巨大的,特别是嵌套,更吓人。

    我对此测试的原因是质疑,质疑的原因是windows程序的结构化异常捕获的SEH链我比较了解。虽然不知道asp.net是如何实现异常捕获机制的,但是看来开销和SEH链一样的巨大。

    我认为异常机制不能用作模块间传递信息的方式,只是在你不知道程序什么时候故障的时候才使用这个机制。例如网络错误,在访问数据库的时候发生了故障等等,这些发生几率很小的地方用异常机制。

    如果在web上传递信息的时候采用了异常机制,那么并发量大的情况下,这个开销将是吓人的。

    创建对象

    这里的计时没法用DateTime了,因为我使用的方法里面也没有一个延时的机制,执行时间小于毫秒级。所以借助了网上一位仁兄的高精度计时器,省得自己去写一个。http://dotnet.chinaitlab.com/ASPNET/742827.html

    Ok,下面是我的程序

    public class MyClass

        {

            public MyClass()

            {

                menber1 = "";

                menber2 = 0;

                m3 = DateTime.Now;

            }

            protected string menber1;

            protected int menber2;

            protected DateTime m3;

            public int TetsObj()

            {

                return 0;

            }

            public static int TestStatic()

            {

                return 0;

            }

        }

    这是被测试的类,有一个静态方法和实例方法。

    protected void Page_Load(object sender, EventArgs e)

            {

                MyTimer mt = new MyTimer();

                double t = mt.GetAbsoluteTime();

                MyClass.TestStatic();

                double t1 = mt.GetAbsoluteTime();

                MyClass mc = new MyClass();

                double t2 = mt.GetAbsoluteTime();

                mc.TetsObj();

                double t3 = mt.GetAbsoluteTime();

                Response.Write((t1 - t));

                Response.Write("<br />");

                Response.Write((t2 - t1));

                Response.Write("<br />");

                Response.Write((t3 - t2));

                Response.Write("<br />");

            }

    这是测试页面。

    下面看输出吧。返回的秒数,也就是多少秒

    7.47301692172186E-05
    0.000180958753844607
    7.9339692092617E-05

    这是第一次启动vs2008调试的时候的数据。

    1.18730167741887E-06
    6.49524008622393E-06
    1.25714177556802E-06

    第一次刷新的数据。

    1.18730167741887E-06
    4.74920670967549E-06
    1.18730167741887E-06

    再次刷新。

    2.09523932426237E-06
    8.73015960678458E-06
    2.09523750527296E-06
    again   refresh

    2.09523932426237E-06
    8.52063567435835E-06
    2.16507942241151E-06
    again

    大概就是这样了。可以看到创建一个对象的时间是调用一个函数的开销的大约4倍以上时间。第一次启动的时候当然这个差距太大了,这是由于object pooling的原因。另外调用静态方法和实例方法的开销一样,如果准确的说,那就是静态方法很多时候更快。

    所以,我觉得很多牛人说的没错,创建对象的开销很大,在一个并发很高的web系统里面需要对此进行优化。

    测试object    pooling

    测试的函数,在MyClass类添加两个方法:

    public static void Test1()

            {

                MyClass mc1 = new MyClass();

            }

            public static void Test2()

            {

                MyClass mc1 = new MyClass();

                MyClass mc2 = new MyClass();

            }

            public static void Test3()

            {

                MyClass mc1 = new MyClass();

                MyClass mc2 = new MyClass();

                MyClass mc3 = new MyClass();

        }

    页面测试方法:

    protected void Page_Load(object sender, EventArgs e)

            {

                MyTimer mt = new MyTimer();

                double t = mt.GetAbsoluteTime();

                MyClass.Test1();

                double t1 = mt.GetAbsoluteTime();

                MyClass.Test1();

                double t2 = mt.GetAbsoluteTime();

                MyClass.Test1();

                double t3 = mt.GetAbsoluteTime();

                MyClass.Test1();

                double t4 = mt.GetAbsoluteTime();

                MyClass.Test2();

                double t5 = mt.GetAbsoluteTime();

                MyClass.Test2();

                double t6 = mt.GetAbsoluteTime();

                MyClass.Test3();

                double t7 = mt.GetAbsoluteTime();

                MyClass.Test3();

                double t8 = mt.GetAbsoluteTime();

                Response.Write((t1 - t));

                Response.Write("<br />");

                Response.Write((t2 - t1));

                Response.Write("<br />");

                Response.Write((t3 - t2));

                Response.Write("<br />");

                Response.Write((t4 - t3));

                Response.Write("<br />");

                Response.Write((t5 - t4));

                Response.Write("<br />");

                Response.Write((t6 - t5));

                Response.Write("<br />");

                Response.Write((t7 - t6));

                Response.Write("<br />");

                Response.Write((t8 - t7));

            }

    输出的结果:

    首次启动:

    0.000266234954324318

    1.18730167741887E-06

    1.11745976028033E-06

    1.11745976028033E-06

    0.000111815887066768

    1.39682742883451E-06

    0.000126622238894925

    1.81587165570818E-06

    第一次调用Test1(),花费了巨大的时间。再次连续调用三次,花费的时间是大概差不多的,但是与第一次相比相差几个数量级。

    然后调用Test2(),比Test1()多创建了一个对象,时间又回到了和第一次差不多,多了几个数量级。

    再次调用Test2(),时间又降低了几个数量级。

    调用Test3(),又多了一个对象创建,时间又反弹上去了。最后调用Test3(),时间又降低了下来。

    Dotnetobject pooling效果由此可见。所以,当一个应用不断地创建对象,并发量大的时候,内存是提高效率的最重要的手段了。内存不是要够,而是要富裕。如果很多对象被Pooling了,效率自然就会提高。
  • 相关阅读:
    Android Virtual Device(AVD)屏幕大小调整
    修改obj三维模型文件中坐标z为其相反数
    AE安装检测(C++)
    单件模式
    地形转立体实验截图
    保持几何特征的三维建筑物模型简化方法 毕业硕士论文
    判断多边形点串存放序列
    mathematica 查找 mathpass 注册文件位置
    在线调色板搜集
    图标资源搜集
  • 原文地址:https://www.cnblogs.com/worldreason/p/1236329.html
Copyright © 2011-2022 走看看