Search Unity

Can someone explain how using as is faster then not in this experiment.

Discussion in 'Scripting' started by Xavier78, Aug 29, 2019.

  1. Xavier78

    Xavier78

    Joined:
    Oct 13, 2013
    Posts:
    41
    So I have this script, which on average the "as" part takes 5600ms, and the other part takes 6000ms!?!?!?


    Code (CSharp):
    1. using System.Diagnostics;
    2. using System.Runtime.CompilerServices;
    3. using UnityEngine;
    4. using Debug = UnityEngine.Debug;
    5. using Random = UnityEngine.Random;
    6. public class TestPasser : MonoBehaviour
    7. {
    8.     const int Iterations = 100000000;
    9.  
    10.     public InfoBase[] types;
    11.     public InfoDog Dog;
    12.     public InfoBook Book;
    13.     public InfoCar Car;
    14.  
    15.     public void Start()
    16.     {
    17.         int total = 0;
    18.  
    19.         Stopwatch sw = Stopwatch.StartNew();
    20.         for (int i = 0; i < Iterations; i++)
    21.         {
    22.             var holder = Random.Range(0, 3);
    23.             if (holder == 0)
    24.             {
    25.                 total += knowTypeDog(types[0] as InfoDog);
    26.             }
    27.             if (holder == 1)
    28.             {
    29.                 total += knowTypeBook(types[1] as InfoBook);
    30.             }
    31.             if (holder == 2)
    32.             {
    33.                 total += knowTypeCar(types[2] as InfoCar);
    34.             }
    35.         }
    36.         sw.Stop();
    37.  
    38.         Debug.Log("typeof(Test): " + sw.ElapsedMilliseconds + "ms " + total);
    39.  
    40.         total = 0;
    41.  
    42.         sw = Stopwatch.StartNew();
    43.         for (int i = 0; i < Iterations; i++)
    44.         {
    45.             var holder = Random.Range(0, 3);
    46.             if (holder == 0)
    47.             {
    48.                 total += knowTypeDog(Dog);
    49.             }
    50.             if (holder == 1)
    51.             {
    52.                 total += knowTypeBook(Book);
    53.             }
    54.             if (holder == 2)
    55.             {
    56.                 total += knowTypeCar(Car);
    57.             }
    58.         }
    59.         sw.Stop();
    60.         Debug.Log("typeof(Test): " + sw.ElapsedMilliseconds + "ms " + total);
    61.     }
    62.  
    63.     [MethodImpl(MethodImplOptions.NoInlining)]
    64.     private int knowTypeDog(InfoDog info)
    65.     {
    66.         return 1;
    67.     }
    68.  
    69.     [MethodImpl(MethodImplOptions.NoInlining)]
    70.     private int knowTypeBook(InfoBook info)
    71.     {
    72.         return 2;
    73.     }
    74.  
    75.     [MethodImpl(MethodImplOptions.NoInlining)]
    76.     private int knowTypeCar(InfoCar info)
    77.     {
    78.         return 3;
    79.     }
    80. }
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    These might not matter at all, but you might consider swapping the order of your tests to see if that matters, and you might also consider using a fixed random seed that is the same for both tests.
     
    Xavier78 likes this.
  3. Xavier78

    Xavier78

    Joined:
    Oct 13, 2013
    Posts:
    41
    switching them actually did have an effect, do you know why this is? I mean clearly now the none "as" is a tinny bit faster based on averages.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    The reason that I generally pay attention to the ordering of things in timing tests is because of caching. Modern computers do a lot of work behind the scenes to try to make your software run faster, and one of the things they do is have a little bit of "special" memory that's faster than normal memory and is used as a "cache", meaning they copy stuff in there temporarily (while you're using it) so that it can read and write it faster than normal.

    That means if you do something with the same bit of data over and over in a loop, the first time is often significantly slower than the repeats. The first time, it has to go fetch the data from main memory (a "cache miss"), but on the repeats it just uses the copy it already has in the extra-fast area (a "cache hit").

    Caching can be hard to predict because the computer is guessing what data you're going to want in the future. However, I would have expected that caching issues would make your first test slower, and it sounds like your actual result is that your first test is faster. So that's...a bit weird.



    This could also hypothetically be caused by something related to your test environment--something else going on in your program during part of your test that changes how it runs for only that part. For instance, if you were running several threads and your computer had to split time between them, that could make your code appear to run "slower" (because it has to share time on the CPU with other threads).
     
    Ryiah likes this.