为了账号安全,请及时绑定邮箱和手机立即绑定

C#是操作员的绩效

C#是操作员的绩效

九州编程 2019-10-18 14:05:37
我有一个需要快速性能的程序。在其内部循环之一中,我需要测试对象的类型,以查看其是否从某个接口继承。一种方法是使用CLR的内置类型检查功能。最优雅的方法可能是'is'关键字:if (obj is ISpecialType)另一种方法是为基类提供我自己的虚拟GetType()函数,该函数返回预定义的枚举值(在我的情况下,实际上,我只需要一个布尔值)。该方法将很快,但不太优雅。我听说有一个专门针对'is'关键字的IL指令,但这并不意味着它在转换为本地程序集时执行速度很快。谁能对“是”与其他方法的性能分享一些见解?更新: 感谢您提供所有明智的答案!答案中似乎有几个有用的观点:安德鲁(Andrew)关于“是否”自动执行演员表的观点是必不可少的,但是Binary Worrier和Ian收集的性能数据也非常有用。如果对其中一个答案进行编辑以包括所有这些信息,那将是非常不错的。
查看完整描述

3 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

我和Ian在一起,您可能不想这样做。


但是,您知道,两者之间的差异很小,超过10,000,000次迭代


枚举检查 大约需要700毫秒

IS检查 大约在 1000毫秒内

我个人不会以这种方式解决此问题,但是如果我被迫选择一种方法将是内置的IS检查,则性能差异不值得考虑编码开销。


我的基础和派生类


class MyBaseClass

{

    public enum ClassTypeEnum { A, B }

    public ClassTypeEnum ClassType { get; protected set; }

}


class MyClassA : MyBaseClass

{

    public MyClassA()

    {

        ClassType = MyBaseClass.ClassTypeEnum.A;

    }

}

class MyClassB : MyBaseClass

{

    public MyClassB()

    {

        ClassType = MyBaseClass.ClassTypeEnum.B;

    }

}

JubJub:根据要求提供有关测试的更多信息。


我从控制台应用程序(调试版本)运行了两个测试,每个测试如下所示


static void IsTest()

{

    DateTime start = DateTime.Now;

    for (int i = 0; i < 10000000; i++)

    {

        MyBaseClass a;

        if (i % 2 == 0)

            a = new MyClassA();

        else

            a = new MyClassB();

        bool b = a is MyClassB;

    }

    DateTime end = DateTime.Now;

    Console.WriteLine("Is test {0} miliseconds", (end - start).TotalMilliseconds);

}

在发行版中运行,像Ian一样,我得到60到70毫秒的时间差。


进一步的更新-2012年10月25日

几年之后,我注意到了一些有关此内容的信息,编译器可以选择省略bool b = a is MyClassB发行版,因为b并未在任何地方使用。


此代码。。。


public static void IsTest()

{

    long total = 0;

    var a = new MyClassA();

    var b = new MyClassB();

    var sw = new Stopwatch();

    sw.Start();

    for (int i = 0; i < 10000000; i++)

    {

        MyBaseClass baseRef;

        if (i % 2 == 0)

            baseRef = a;//new MyClassA();

        else

            baseRef = b;// new MyClassB();

        //bool bo = baseRef is MyClassB;

        bool bo = baseRef.ClassType == MyBaseClass.ClassTypeEnum.B;

        if (bo) total += 1;

    }

    sw.Stop();

    Console.WriteLine("Is test {0} miliseconds {1}", sw.ElapsedMilliseconds, total);

}

。。。始终显示is检查大约需要57毫秒,而枚举比较大约需要29毫秒。


注意: 我还是希望is支票,差额太小,无法在意


查看完整回答
反对 回复 2019-10-18
  • 3 回答
  • 0 关注
  • 591 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信