about casting

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tony Johansson

    about casting

    Hello!

    Here I have two different way to use casting.
    Is any of these any better then the other?
    Or is it just a question of taste.

    newCards.Add((C ard)sourceCard. Clone());
    newCards.Add(so urceCard.Clone( ) as Card);

    //Tony


  • Jon Skeet [C# MVP]

    #2
    Re: about casting

    Tony Johansson <johansson.ande rsson@telia.com wrote:
    Here I have two different way to use casting.
    Is any of these any better then the other?
    Or is it just a question of taste.
    >
    newCards.Add((C ard)sourceCard. Clone());
    newCards.Add(so urceCard.Clone( ) as Card);
    Using "as" doesn't throw an exception if the cast fails - it just
    returns null instead.

    Using a direct cast also allows for user-defined conversions etc.

    I tend to use "as" for values I'm in doubt about - when I'm about to
    test the result:

    Object unknown = GetMeSomeData() ;
    string text = unknown as string;
    if (text != null)
    {
    ...
    }


    I use direct casting when I really, really expect it to succeed - i.e.
    when a failure indicates a problem which should be reported as an
    exception:

    Object shouldBeString = GetMeSomeText() ;
    string text = (string) shouldBeString;

    --
    Jon Skeet - <skeet@pobox.co m>
    Web site: http://www.pobox.com/~skeet
    Blog: http://www.msmvps.com/jon.skeet
    C# in Depth: http://csharpindepth.com

    Comment

    • Marc Gravell

      #3
      Re: about casting

      One other note; "as" can only be used with reference types and
      Nullable<T>, as it can't return null for a regular struct. You'd need
      to use "is" and cast to achieve the same.

      Marc

      Comment

      • Hilton

        #4
        Re: about casting

        Tony,

        I use "as" because it is much faster than the "(Card)" variety of casting.
        Also, I think "(vehicle as Car).Color" looks a lot cleaner than "((Car)
        vehicle).Color" . That's my preference though - others might think "(Car)"
        looks better. Let me preempt my fellow NGers by saying that you should only
        optimize yada yada yada. I say, ya know what, I'm developing on mobile
        devices running a 200MHz, I'm gonna use every little speed enhancement I can
        get especially when it is for free.

        Very important to note is that they are different as Jon pointed out, so
        sometimes it makes sense to use one instead of the other.

        Anyway, there you go.

        Hilton



        "Tony Johansson" <johansson.ande rsson@telia.com wrote in message
        news:pkV3k.21$U 5.590@newsb.tel ia.net...
        Hello!
        >
        Here I have two different way to use casting.
        Is any of these any better then the other?
        Or is it just a question of taste.
        >
        newCards.Add((C ard)sourceCard. Clone());
        newCards.Add(so urceCard.Clone( ) as Card);
        >
        //Tony
        >

        Comment

        • =?Utf-8?B?U3VqZWV0?=

          #5
          Re: about casting

          Hilton,
          Why is 'as' much faster that (Card), except in cases where (Card) might
          throw an exception?
          Otherwise, I think in both cases the CLR needs to walk the same level of
          object type structures and so should be have the same running time.

          Sujeet

          "Hilton" wrote:
          Tony,
          >
          I use "as" because it is much faster than the "(Card)" variety of casting.
          Also, I think "(vehicle as Car).Color" looks a lot cleaner than "((Car)
          vehicle).Color" . That's my preference though - others might think "(Car)"
          looks better. Let me preempt my fellow NGers by saying that you should only
          optimize yada yada yada. I say, ya know what, I'm developing on mobile
          devices running a 200MHz, I'm gonna use every little speed enhancement I can
          get especially when it is for free.
          >
          Very important to note is that they are different as Jon pointed out, so
          sometimes it makes sense to use one instead of the other.
          >
          Anyway, there you go.
          >
          Hilton
          >
          >
          >
          "Tony Johansson" <johansson.ande rsson@telia.com wrote in message
          news:pkV3k.21$U 5.590@newsb.tel ia.net...
          Hello!

          Here I have two different way to use casting.
          Is any of these any better then the other?
          Or is it just a question of taste.

          newCards.Add((C ard)sourceCard. Clone());
          newCards.Add(so urceCard.Clone( ) as Card);

          //Tony
          >
          >
          >

          Comment

          • Scott M.

            #6
            Re: about casting

            Actually, I think the DirectCast version: (string) x is faster (by design)
            as long as you don't get an exception because that version is meant to do
            the cast without checking to see if the cast is doable first.

            -Scott


            "Sujeet" <Sujeet@discuss ions.microsoft. comwrote in message
            news:635323C2-F694-4900-A629-71433DD43B57@mi crosoft.com...
            Hilton,
            Why is 'as' much faster that (Card), except in cases where (Card) might
            throw an exception?
            Otherwise, I think in both cases the CLR needs to walk the same level of
            object type structures and so should be have the same running time.
            >
            Sujeet
            >
            "Hilton" wrote:
            >
            >Tony,
            >>
            >I use "as" because it is much faster than the "(Card)" variety of
            >casting.
            >Also, I think "(vehicle as Car).Color" looks a lot cleaner than "((Car)
            >vehicle).Color ". That's my preference though - others might think
            >"(Car)"
            >looks better. Let me preempt my fellow NGers by saying that you should
            >only
            >optimize yada yada yada. I say, ya know what, I'm developing on mobile
            >devices running a 200MHz, I'm gonna use every little speed enhancement I
            >can
            >get especially when it is for free.
            >>
            >Very important to note is that they are different as Jon pointed out, so
            >sometimes it makes sense to use one instead of the other.
            >>
            >Anyway, there you go.
            >>
            >Hilton
            >>
            >>
            >>
            >"Tony Johansson" <johansson.ande rsson@telia.com wrote in message
            >news:pkV3k.21$ U5.590@newsb.te lia.net...
            Hello!
            >
            Here I have two different way to use casting.
            Is any of these any better then the other?
            Or is it just a question of taste.
            >
            newCards.Add((C ard)sourceCard. Clone());
            newCards.Add(so urceCard.Clone( ) as Card);
            >
            //Tony
            >
            >>
            >>
            >>

            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: about casting

              On Jun 12, 2:44 am, "Hilton" <nos...@nospam. comwrote:
              I use "as" because it is much faster than the "(Card)" variety of casting.
              No it's not. At least, it's not on the desktop CLR.

              It's faster to use "as" and then a comparison with null than it is to
              use "is" and then a direct cast, but if you're just casting then
              they're about the same - with casting coming out slightly on top in
              one microbenchmark I've just run:

              using System;
              using System.Diagnost ics;

              public class Test
              {
              static void Main(string[] args)
              {
              object o = "hello";
              int iterations = int.Parse(args[0]);
              int total = 0;
              Stopwatch sw = Stopwatch.Start New();
              for (int i=0; i < iterations; i++)
              {
              total += Cast(o).Length;
              }
              sw.Stop();
              Console.WriteLi ne(total);
              Console.WriteLi ne(sw.ElapsedMi lliseconds);
              }

              static string Cast(object o)
              {
              return (string)o;
              }

              static string As(object o)
              {
              return o as string;
              }
              }

              Change the call appropriately to test the different methods, and then
              change the calling code to have the cast/as directly in the loop:

              Running with 2,000,000,000 iterations, 3 runs each
              As: 9595, 9567m 9565
              Cast: 7180, 7199, 7216
              As inline: 6355, 6393, 6595
              Cast inline: 4777, 4807, 4812

              Normal caveats about microbenchmarks apply, but I'd be interested to
              see the results of you running the above tests on the CF. It certainly
              looks to me like "as" is marginally slower, and certainly far from
              "much faster".
              Also, I think "(vehicle as Car).Color" looks a lot cleaner than "((Car)
              vehicle).Color" . That's my preference though - others might think "(Car)"
              looks better. Let me preempt my fellow NGers by saying that you should only
              optimize yada yada yada. I say, ya know what, I'm developing on mobile
              devices running a 200MHz, I'm gonna use every little speed enhancement I can
              get especially when it is for free.
              Except it's not for free anyway - it means you get a
              NullReferenceEx ception instead of an InvalidCastExce ption if
              anything's wrong, and that's if you're lucky and use the referece
              immediately. Using "as" when you really expect a cast to work can
              obscure the origin of a bug.
              Very important to note is that they are different as Jon pointed out, so
              sometimes it makes sense to use one instead of the other.
              One thing I didn't mention about the difference between the two is
              nulls. If you cast and end up with null, you know that the source was
              null. If you use "as" and end up with null, it's either because the
              original reference was null *or* because it referred to an object of
              the wrong type.

              Jon

              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: about casting

                On Jun 12, 4:19 am, "Scott M." <s...@nospam.no spamwrote:
                Actually, I think the DirectCast version: (string) x is faster (by design)
                as long as you don't get an exception because that version is meant to do
                the cast without checking to see if the cast is doable first.
                No, it's still got to do the cast to see whether or not you *do* get
                an exception. As it happens it seems like it's marginally faster on
                the current desktop CLR - I think it may have been the other way round
                at some point. The important part is that both of them actually need
                to do the same expensive bit of work: check whether a cast is valid.
                What happens after that is relatively cheap (in the success case).

                Jon

                Comment

                • Hilton

                  #9
                  Re: about casting

                  Jon Skeet wrote:
                  Normal caveats about microbenchmarks apply, but I'd be interested to
                  see the results of you running the above tests on the CF. It certainly
                  looks to me like "as" is marginally slower, and certainly far from
                  "much faster".
                  I remember doing this test after seeing an article in CodeProject and my
                  results definitely showed that "as" was much faster - see the CodeProject
                  article: http://69.10.233.10/KB/cs/csharpcasts.aspx

                  To verify before I posted my earlier post today, I ran some code on my
                  desktop. The two inner loops looked like:

                  {
                  Blob b = (Blob) o;
                  }

                  and

                  {
                  Blob b = o as Blob;
                  }

                  ....and the second version was indeed *much* faster than the first, so I was
                  confident posting that it was much faster. Only when I went back and
                  thought about it, I realized that the compiler could safely remove "o as
                  Blob", but *not* "(Blob) o" - right? So, I was, in effect, testing compiler
                  optimization which I am glad to say is alive and well. OK, perhaps I had
                  originally tested in on CF 1. So I wrote a quick app, ran it on my X51 and
                  the two versions ran in exactly the same time (give or take). The
                  CodeProject guy never posted any code, perhaps he made the same "compiler
                  optimization" error as I did.

                  Interestingly though, the two are very different beasts, used in different
                  circumstances, and definitely help to self-document if used correctly. The
                  cool thing though is that C# has both of these tools.

                  OK, I was wrong - sorry about that and thanks to Jon for correcting me.

                  Hilton


                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: about casting

                    On Jun 12, 8:26 am, "Hilton" <nos...@nospam. comwrote:
                    Jon Skeet wrote:
                    Normal caveats about microbenchmarks apply, but I'd be interested to
                    see the results of you running the above tests on the CF. It certainly
                    looks to me like "as" is marginally slower, and certainly far from
                    "much faster".
                    >
                    I remember doing this test after seeing an article in CodeProject and my
                    results definitely showed that "as" was much faster - see the CodeProject
                    article:http://69.10.233.10/KB/cs/csharpcasts.aspx
                    <snip>

                    Interestingly, there's a post there saying that the performance of
                    direct casting was significantly improved for .NET 2.0 - so that's
                    probably where the confusion comes from.

                    Now, for your particular case it's worth investigating whether that's
                    also true on the CF - or rather, for the particular version of the CF
                    you're using. I wouldn't be surprised if the performance
                    characteristics were quite different there.

                    <snip>
                    Interestingly though, the two are very different beasts, used in different
                    circumstances, and definitely help to self-document if used correctly. The
                    cool thing though is that C# has both of these tools.
                    Yes, it's definitely nice to have both. I do wonder whether "as" might
                    not be better as a slightly different language construct though -
                    something to do:

                    Foo x = y as Foo;
                    if (x != null)
                    {
                    ...
                    }

                    in one block, e.g.:

                    when (Foo x = y)
                    {
                    ...
                    }

                    I'm not sure though. (And I certainly wouldn't want to introduce it
                    now - just an idea of what might have been nice at 1.0.)

                    Jon

                    Comment

                    • Hilton

                      #11
                      Re: about casting

                      Jon Skeet wrote:
                      Interestingly, there's a post there saying that the performance of
                      direct casting was significantly improved for .NET 2.0 - so that's
                      probably where the confusion comes from.
                      Here are the CF numbers:

                      Running 1.0.4292.0:

                      33:13 <--start time
                      33:39 <--after () cast, before "as"
                      34:05 <--end time

                      i.e. both took 26 seconds


                      Running 2.0.7045.0:

                      35:04
                      35:11
                      35:18

                      i.e. both took 7 seconds - nice!

                      My app runs a lot zippier on CF2 than CF1. I don't recall noticing a huge
                      increase from 2.0 to 3.5, I'd need to do some timing, but 1.0 to 2.0 was
                      very noticable. Thank you Microsoft.

                      Hilton


                      Comment

                      • Jon Skeet [C# MVP]

                        #12
                        Re: about casting

                        On Jun 12, 10:16 am, "Tony Johansson" <johansson.ande rs...@telia.com >
                        wrote:
                        Here you are talking about CF what is that?
                        The Compact Framework - a version of .NET used for mobile devices like
                        PDAs.

                        (There's also the .NET Micro Edition, but I don't know how widely used
                        that is.)

                        Jon

                        Comment

                        • Marc Gravell

                          #13
                          Re: about casting

                          The Compact Framework - a version of .NET used for mobile devices like
                          PDAs.
                          (There's also the .NET Micro Edition, but I don't know how widely used
                          that is.)
                          And the Silverlight framework; to be honest I haven't done enough
                          digging to know if this re-uses any of the others, or is just a
                          completely different architecture, but it is yet another .NET host ;-p

                          [out of interest, if anybody else knows... ?]

                          Marc

                          Comment

                          • Cor Ligthert [MVP]

                            #14
                            Re: about casting

                            Jon,
                            >
                            Using a direct cast also allows for user-defined conversions etc.
                            >
                            Are you sure of this, I thought that it was the opposite

                            (As that is the way the DirectCast in VB for Net is working oposite the
                            CType (Convert or Cast Type), which are in my idea a little bit equivalent
                            to this. The DirectCast should be sometimes slightly quicker, those things I
                            never measure)

                            Cor


                            Comment

                            • Marc Gravell

                              #15
                              Re: about casting

                              Using a direct cast also allows for user-defined conversions etc.
                              >
                              Are you sure of this, I thought that it was the opposite
                              cast will use defined implicit/explicit operators; "as" doesn't - you
                              get this instead:

                              "Cannot convert type 'Bar' to 'Foo' via a reference conversion, boxing
                              conversion, unboxing conversion, wrapping conversion, or null type
                              conversion"

                              In the ECMA spec, sections 14.6.6 and 14.9.11

                              Marc

                              Comment

                              Working...