views:

94

answers:

1

Hi all. First, I was trying to do something like :

class Class1
{
    public void Do()
    {
    }
}
class Class2
{
    public void Do()
    {
    }
}

...

if (o is Class1)
{
    Class1 c = (Class1)o;
    c.Do();
}
if (o is Class2)
{
    Class2 c = (Class2)o;
    c.Do();
}

but fxcop tells me that : Performance Rules, Avoid duplicate casts where possible, since there is a cost associated with them. Cache the result of the 'as' operator ...

So I've done :

Class1 c1 = o as Class1;
Class2 c2 = o as Class2;
if (c1 != null)
    c1.Do();
if (c2 != null)
    c2.Do();

and no more fxcop error. But I've try to measure if it's really a good Performance rule with :

static void Main()
    {
        object o = new Class1();
        int cst = 100000000;

        Stopwatch sw1 = new Stopwatch();
        Stopwatch sw2 = new Stopwatch();
        sw1.Start();
        for (int i = 0; i < cst; i++)
        {
            GoodPerf(o);
        }
        sw1.Stop();
        var t1 = sw1.ElapsedMilliseconds;

        sw2.Start();
        for (int i = 0; i < cst; i++)
        {
            BadPerf(o);
        }
        sw2.Stop();
        var t2 = sw2.ElapsedMilliseconds;
        Console.WriteLine(t1);
        Console.WriteLine(t2);
    }

    private static void BadPerf(object o)
    {
        if (o is Class1)
        {
            Class1 c = (Class1)o;
            c.Do();
        }
        if (o is Class2)
        {
            Class2 c = (Class2)o;
            c.Do();
        }
    }

    private static void GoodPerf(object o)
    {
        Class1 c1 = o as Class1;
        Class2 c2 = o as Class2;
        if (c1 != null)
            c1.Do();
        if (c2 != null)
            c2.Do();
    }

And it displays :

2090
1725

2090 is supposed to be the good perf ...

So ... I'm asking if I really should to follow this rule ... Maybe, I'm not correcting the good way...

Thanks for your answer

+1  A: 

FxCop isn't always right, it's oversimplifying sometimes and this is one of the most common scenarios. Unless you're casting 3 or 4+ times, you're not going to outweigh the cost of the as operator...but the FxCop rule doesn't check like this, it just does >1

Maybe it will be better check with 4.0 VS release? I assume since dynamic is out there, they've had to revisit a lot of these rules, but we won't know until it ships probably. The beta 2 I have still currently checks in the style you posted, giving some bad advice in this case IMO.

However, keep in mind that this is minuscule in terms of performance, not something to worry about unless you're looping hundreds of thousands of times.

Something else to keep in mind, if you look at the IL then part of the time it in-lines the damn thing anyway, making the warning completely useless.

Nick Craver
you're maybe right.I will forget this rule :)thanks for your answer
Tim