当前位置:  开发笔记 > 编程语言 > 正文

是vs typeof

如何解决《是vstypeof》经验,为你挑选了4个好方法。

这些代码中的哪一段更快?

if (obj is ClassA) {}

if (obj.GetType() == typeof(ClassA)) {}

编辑:我知道他们不会做同样的事情.



1> Jay Bazuzi..:

如果他们不做同样的事情,哪个更快更重要?比较具有不同含义的陈述的表现似乎是一个坏主意.

is告诉你对象是否ClassA在其类型heirarchy中的任何地方实现. GetType()告诉你最派生的类型.

不一样的事情.


@ [ilitirit]:他们现在返回相同的结果,但如果你稍后添加一个子类,他们就不会
现在优化将使您的代码变得脆弱且难以维护.
我的课程是密封的.
这很重要,因为在我的情况下,我肯定他们会返回相同的结果.

2> MagicKat..:

这应该回答这个问题,然后是一些问题.

if (obj.GetType() == typeof(ClassA)) {}对于那些不想阅读文章的人来说,第二行更快.


请阅读http://higherlogics.blogspot.ca/2013/09/clr-cost-of-dynamic-type-tests.html - 他们重新测试不同的框架和x86与x64,结果差异很大.

3> tvanfosson..:

他们不做同样的事情.如果obj是ClassA类型或ClassA的某个子类,则第一个工作.第二个只匹配ClassA类型的对象.第二个会更快,因为它不必检查类层次结构.

对于那些想知道原因,但又不想阅读引用文章的人 是vs typeof.



4> nawfal..:

我做了一些基准测试,他们做同样的事情 - 密封类型.

var c1 = "";
var c2 = typeof(string);
object oc1 = c1;
object oc2 = c2;

var s1 = 0;
var s2 = '.';
object os1 = s1;
object os2 = s2;

bool b = false;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
    b = c1.GetType() == typeof(string); // ~60ms
    b = c1 is string; // ~60ms

    b = c2.GetType() == typeof(string); // ~60ms
    b = c2 is string; // ~50ms

    b = oc1.GetType() == typeof(string); // ~60ms
    b = oc1 is string; // ~68ms

    b = oc2.GetType() == typeof(string); // ~60ms
    b = oc2 is string; // ~64ms


    b = s1.GetType() == typeof(int); // ~130ms
    b = s1 is int; // ~50ms

    b = s2.GetType() == typeof(int); // ~140ms
    b = s2 is int; // ~50ms

    b = os1.GetType() == typeof(int); // ~60ms
    b = os1 is int; // ~74ms

    b = os2.GetType() == typeof(int); // ~60ms
    b = os2 is int; // ~68ms


    b = GetType1(c1); // ~178ms
    b = GetType2(c1); // ~94ms
    b = Is(c1); // ~70ms

    b = GetType1(c2); // ~178ms
    b = GetType2(c2); // ~96ms
    b = Is(c2); // ~65ms

    b = GetType1(oc1); // ~190ms
    b = Is(oc1); // ~69ms

    b = GetType1(oc2); // ~180ms
    b = Is(oc2); // ~64ms


    b = GetType1(s1); // ~230ms
    b = GetType2(s1); // ~75ms
    b = Is(s1); // ~136ms

    b = GetType1(s2); // ~238ms
    b = GetType2(s2); // ~69ms
    b = Is(s2); // ~142ms

    b = GetType1(os1); // ~178ms
    b = Is(os1); // ~69ms

    b = GetType1(os2); // ~178ms
    b = Is(os2); // ~69ms
}

sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());

用于测试泛型类型的通用函数:

static bool GetType1(T t)
{
    return t.GetType() == typeof(S);
}
static bool GetType2(T t)
{
    return typeof(T) == typeof(S);
}
static bool Is(T t)
{
    return t is S;
}

我也试过自定义类型,结果是一致的:

var c1 = new Class1();
var c2 = new Class2();
object oc1 = c1;
object oc2 = c2;

var s1 = new Struct1();
var s2 = new Struct2();
object os1 = s1;
object os2 = s2;

bool b = false;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
    b = c1.GetType() == typeof(Class1); // ~60ms
    b = c1 is Class1; // ~60ms

    b = c2.GetType() == typeof(Class1); // ~60ms
    b = c2 is Class1; // ~55ms

    b = oc1.GetType() == typeof(Class1); // ~60ms
    b = oc1 is Class1; // ~68ms

    b = oc2.GetType() == typeof(Class1); // ~60ms
    b = oc2 is Class1; // ~68ms


    b = s1.GetType() == typeof(Struct1); // ~150ms
    b = s1 is Struct1; // ~50ms

    b = s2.GetType() == typeof(Struct1); // ~150ms
    b = s2 is Struct1; // ~50ms

    b = os1.GetType() == typeof(Struct1); // ~60ms
    b = os1 is Struct1; // ~64ms

    b = os2.GetType() == typeof(Struct1); // ~60ms
    b = os2 is Struct1; // ~64ms


    b = GetType1(c1); // ~178ms
    b = GetType2(c1); // ~98ms
    b = Is(c1); // ~78ms

    b = GetType1(c2); // ~178ms
    b = GetType2(c2); // ~96ms
    b = Is(c2); // ~69ms

    b = GetType1(oc1); // ~178ms
    b = Is(oc1); // ~69ms

    b = GetType1(oc2); // ~178ms
    b = Is(oc2); // ~69ms


    b = GetType1(s1); // ~272ms
    b = GetType2(s1); // ~140ms
    b = Is(s1); // ~163ms

    b = GetType1(s2); // ~272ms
    b = GetType2(s2); // ~140ms
    b = Is(s2); // ~163ms

    b = GetType1(os1); // ~178ms
    b = Is(os1); // ~64ms

    b = GetType1(os2); // ~178ms
    b = Is(os2); // ~64ms
}

sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());

和类型:

sealed class Class1 { }
sealed class Class2 { }
struct Struct1 { }
struct Struct2 { }

推理:

    调用GetTypestructs是慢. GetType是在object类上定义的,不能在子类型中重写,因此struct需要将其装箱以进行调用GetType.

    在对象实例上,GetType速度更快,但非常轻微.

    在泛型类型上,如果Tclass,则is更快.如果Tstruct,那么比两者is快得多GetTypetypeof(T)速度要快得多.在案件T之中class,typeof(T)是不是因为从实际的基本类型及其不同的可靠t.GetType.

简而言之,如果您有object实例,请使用GetType.如果您有通用class类型,请使用is.如果您有通用struct类型,请使用typeof(T).如果您不确定泛型类型是引用类型还是值类型,请使用is.如果您希望始终与一种样式保持一致(对于密封类型),请使用is..

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有