Search Unity

Which is faster, SendMessage or GetComponent?

Discussion in 'Scripting' started by cat_ninja, Sep 10, 2011.

  1. cat_ninja

    cat_ninja

    Joined:
    Jul 14, 2010
    Posts:
    197
    Hi, I'm currently working on an RTS project and I have a lot of changing variables between units and the camera. I was just wondering would it be better to just change the public variables via GetComponent or just to SendMessages and change the variables with void functions. I'm doing this in C# by the way. And I'm kindof a noobish scripter :D
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    GetComponent is faster.

    A dictionary is probably faster still.
     
  3. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    I've always used GetComponent simply because I like getting compiler errors instead of runtime errors (in the event of, say, a typo). I always assumed it was faster, but never bothered testing. I was bored - so I did this:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class TestSender : MonoBehaviour {
    6.     public int iterations = 1000;
    7.    
    8.     public Collider other;
    9.     double lastSendMessage;
    10.     double lastGetComponent;
    11.     double lastSendMessageVerified;
    12.     double lastGetComponentVerified;
    13.     double lastGetComponentVerifiedViaTag;
    14.    
    15.     string requiredTag = "Player";
    16.    
    17.     // Use this for initialization
    18.     void Start () {
    19.         lastSendMessage = 0;
    20.         lastGetComponent = 0;
    21.     }
    22.    
    23.     // Update is called once per frame
    24.     void Update () {
    25.    
    26.     }
    27.    
    28.     void OnGUI(){
    29.         if (GUILayout.Button("Test SendMessage")){
    30.             StartCoroutine(TestSendMessage());
    31.         }
    32.         if (GUILayout.Button("Test GetComponent")){
    33.             StartCoroutine(TestGetComponent());
    34.         }
    35.         if (GUILayout.Button("Test SendMessage Verified")){
    36.             StartCoroutine(TestSendMessageVerified());
    37.         }
    38.         if (GUILayout.Button("Test GetComponent Verified")){
    39.             StartCoroutine(TestGetComponentVerified());
    40.         }
    41.         if (GUILayout.Button("Test GetComponent Verified Via Tag")){
    42.             StartCoroutine(TestGetComponentVerifiedViaTag());
    43.         }
    44.        
    45.         GUILayout.Label("SendMessage: " + lastSendMessage.ToString());
    46.         GUILayout.Label("GetComponent: " + lastGetComponent.ToString());
    47.         GUILayout.Label("SendMessageVerified: " + lastSendMessageVerified.ToString());
    48.         GUILayout.Label("GetComponentVerified: " + lastGetComponentVerified.ToString());
    49.         GUILayout.Label("GetComponentVerifiedViaTag: " + lastGetComponentVerifiedViaTag.ToString());
    50.     }
    51.    
    52.     IEnumerator TestSendMessage(){
    53.         yield return null;
    54.         System.DateTime startTime = System.DateTime.Now;
    55.         yield return null;
    56.        
    57.         for (int i = 0; i < iterations; i++){
    58.             other.SendMessage("TestFunction", SendMessageOptions.DontRequireReceiver);
    59.         }
    60.        
    61.         yield return null;
    62.         System.TimeSpan elapsed = System.DateTime.Now.Subtract(startTime);
    63.         lastSendMessage = elapsed.TotalSeconds;
    64.     }
    65.    
    66.     IEnumerator TestGetComponent(){
    67.         yield return null;
    68.         System.DateTime startTime = System.DateTime.Now;
    69.         yield return null;
    70.        
    71.         for (int i = 0; i < iterations; i++){
    72.             other.GetComponent<TestReceiver>().TestFunction();
    73.         }
    74.        
    75.         yield return null;
    76.         System.TimeSpan elapsed = System.DateTime.Now.Subtract(startTime);
    77.         lastGetComponent = elapsed.TotalSeconds;
    78.     }
    79.    
    80.     IEnumerator TestSendMessageVerified(){
    81.         yield return null;
    82.         System.DateTime startTime = System.DateTime.Now;
    83.         yield return null;
    84.        
    85.         for (int i = 0; i < iterations; i++){
    86.             other.SendMessage("TestFunction", SendMessageOptions.RequireReceiver);
    87.         }
    88.        
    89.         yield return null;
    90.         System.TimeSpan elapsed = System.DateTime.Now.Subtract(startTime);
    91.         lastSendMessageVerified = elapsed.TotalSeconds;
    92.     }
    93.    
    94.     IEnumerator TestGetComponentVerified(){
    95.         yield return null;
    96.         System.DateTime startTime = System.DateTime.Now;
    97.         yield return null;
    98.        
    99.         for (int i = 0; i < iterations; i++){
    100.             TestReceiver found = other.GetComponent<TestReceiver>();
    101.             if (found != null){
    102.                 found.TestFunction();
    103.             }
    104.         }
    105.        
    106.         yield return null;
    107.         System.TimeSpan elapsed = System.DateTime.Now.Subtract(startTime);
    108.         lastGetComponentVerified = elapsed.TotalSeconds;
    109.     }
    110.    
    111.     IEnumerator TestGetComponentVerifiedViaTag(){
    112.         yield return null;
    113.         System.DateTime startTime = System.DateTime.Now;
    114.         yield return null;
    115.        
    116.         for (int i = 0; i < iterations; i++){
    117.             if (other.tag == requiredTag){
    118.                 other.GetComponent<TestReceiver>().TestFunction();
    119.             }
    120.         }
    121.        
    122.         yield return null;
    123.         System.TimeSpan elapsed = System.DateTime.Now.Subtract(startTime);
    124.         lastGetComponentVerifiedViaTag = elapsed.TotalSeconds;
    125.     }
    126. }
    127.  
    128.  
    and

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class TestReceiver : MonoBehaviour {
    6.  
    7.     // Use this for initialization
    8.     void Start () {
    9.    
    10.     }
    11.    
    12.     // Update is called once per frame
    13.     void Update () {
    14.    
    15.     }
    16.    
    17.     public void TestFunction(){
    18.         int i = 0;
    19.     }
    20. }
    21.  
    22.  

    I found that with 2000000 iterations I averaged:

    double lastSendMessage; 1.09 - 1.12 seconds
    double lastGetComponent; 0.42 - 0.46 seconds
    double lastSendMessageVerified; 1.1 - 1.12 seconds
    double lastGetComponentVerified; 0.5 - 0.52 seconds
    double lastGetComponentVerifiedViaTag; 5.9 - 6.2 seconds


    So even with a null check GetComponent was faster every time than SendMessage, by a significant margin. Tag checking before using GetComponent was incredibly slow compared to any other method tested.

    Personally, I'm going to stick with GetComponent<> and null checks. For iOS projects I tend to cache the results in a dictionary - but it's probably not really necessary. For PC/Mac/Web projects I don't even bother with that though.
     
    azurvii likes this.
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    String comparisons aren't that slow; it should be about 3X slower when comparing tags vs. without, rather than 12X slower, so something is quite wrong there. In any case you can use CompareTag() instead of string comparisons to speed things up somewhat. Your timing method isn't very accurate, though, since you're measuring the time it takes to update the frame a couple of times in addition to the calculations. Instead of using coroutines and yielding and so on, do this:

    Code (csharp):
    1. void TestFunction () {
    2.     var timer = Time.realtimeSinceStartup;
    3.    
    4.     // test code here
    5.    
    6.     Debug.Log (Time.realtimeSinceStartup-timer);
    7. }
    That way you only measure the actual calculations. When using that method, you can see that GetComponent vs. SendMessage is actually 3X faster rather than 2.6X faster, since measuring the time it takes to update the frame dilutes the difference somewhat. Also, if you're interested in the best speed, use

    Code (csharp):
    1. ((TestReceiver)other.GetComponent(typeof(TestReceiver))).TestFunction();
    rather than

    Code (csharp):
    1. other.GetComponent<TestReceiver>().TestFunction();
    Not using generics is about 1.5X faster. This also makes GetComponent 5X faster than SendMessage instead of 3X faster. It's true the syntax is a lot more annoying, but note that if you're using JS rather than C#, and you're using at least Unity 3.4, you can just do

    Code (csharp):
    1. other.GetComponent(TestReceiver).TestFunction();
    and you will get the speed improvement over using generics, since GetComponent returns the correct type automatically now, instead of Component.

    --Eric
     
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    JS: language of champions.
     
  6. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    Thank you for the notes, Eric.

    I've been using that coroutine method for so long to test things that I honestly forget why I started doing it in the first place. I've made some changes:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class TestSender : MonoBehaviour {
    7.     public int iterations = 2000000;
    8.    
    9.     public Collider other;
    10.     float lastSendMessage;
    11.     float lastGetComponent;
    12.     float lastSendMessageVerified;
    13.     float lastGetComponentVerified;
    14.     float lastGetComponentVerifiedViaTag;
    15.    
    16.     float lastGetComponentDict;
    17.     float lastGetComponentDictVerified;
    18.    
    19.    
    20.     float tagStringComparison;
    21.     float tagCompareTag;
    22.    
    23.     string requiredTag = "Player";
    24.    
    25.     Dictionary<Collider,TestReceiver> dict;
    26.    
    27.     void Awake () {
    28.         dict = new Dictionary<Collider, TestReceiver>();
    29.        
    30.         for (int i = 0; i < 100; i++){
    31.             GameObject go = new GameObject();
    32.             Collider col = go.AddComponent<BoxCollider>();
    33.            
    34.             dict.Add(col, go.AddComponent<TestReceiver>());
    35.         }
    36.        
    37.         dict.Add(other, other.gameObject.AddComponent<TestReceiver>());
    38.     }
    39.    
    40.     // Use this for initialization
    41.     void Start () {
    42.         lastSendMessage = 0;
    43.         lastGetComponent = 0;
    44.     }
    45.    
    46.     // Update is called once per frame
    47.     void Update () {
    48.    
    49.     }
    50.    
    51.     void OnGUI(){
    52.         if (GUILayout.Button("Test SendMessage")){
    53.             TestSendMessage();
    54.         }
    55.         if (GUILayout.Button("Test GetComponent")){
    56.             TestGetComponent();
    57.         }
    58.         if (GUILayout.Button("Test SendMessage Verified")){
    59.             TestSendMessageVerified();
    60.         }
    61.         if (GUILayout.Button("Test GetComponent Verified")){
    62.             TestGetComponentVerified();
    63.         }
    64.         if (GUILayout.Button("Test GetComponent Verified Via Tag")){
    65.             TestGetComponentVerifiedViaTag();
    66.         }
    67.        
    68.         if (GUILayout.Button("Test GetComponent Via Dict")){
    69.             TestGetComponentDict();
    70.         }
    71.        
    72.         if (GUILayout.Button("Test GetComponent Via Dict Verified")){
    73.             TestGetComponentDictVerified();
    74.         }
    75.        
    76.         if (GUILayout.Button("Test Tag String Comparison")){
    77.             TestTagCompareString();
    78.         }
    79.         if (GUILayout.Button("Test Tag CompareTag")){
    80.             TestTagCompareTag();
    81.         }
    82.        
    83.         GUILayout.Label("SendMessage: " + lastSendMessage.ToString());
    84.         GUILayout.Label("GetComponent: " + lastGetComponent.ToString());
    85.         GUILayout.Label("SendMessageVerified: " + lastSendMessageVerified.ToString());
    86.         GUILayout.Label("GetComponentVerified: " + lastGetComponentVerified.ToString());
    87.         GUILayout.Label("GetComponentVerifiedViaTag: " + lastGetComponentVerifiedViaTag.ToString());
    88.        
    89.         GUILayout.Label("GetComponentDict: " + lastGetComponentDict.ToString());
    90.         GUILayout.Label("GetComponentDictVerified: " + lastGetComponentDictVerified.ToString());
    91.        
    92.         GUILayout.Label("TagCompareString: " + tagStringComparison.ToString());
    93.         GUILayout.Label("TagCompareTag: " + tagCompareTag.ToString());
    94.     }
    95.    
    96.     void TestSendMessage(){
    97.         float timer = Time.realtimeSinceStartup;
    98.        
    99.         for (int i = 0; i < iterations; i++){
    100.             other.SendMessage("TestFunction", SendMessageOptions.DontRequireReceiver);
    101.         }
    102.        
    103.         lastSendMessage = Time.realtimeSinceStartup-timer;
    104.     }
    105.    
    106.     void TestGetComponent(){
    107.         float timer = Time.realtimeSinceStartup;
    108.        
    109.         for (int i = 0; i < iterations; i++){
    110.             other.GetComponent<TestReceiver>().TestFunction();
    111.         }
    112.        
    113.         lastGetComponent = Time.realtimeSinceStartup-timer;
    114.     }
    115.    
    116.     void TestSendMessageVerified(){
    117.         float timer = Time.realtimeSinceStartup;
    118.        
    119.         for (int i = 0; i < iterations; i++){
    120.             other.SendMessage("TestFunction", SendMessageOptions.RequireReceiver);
    121.         }
    122.        
    123.         lastSendMessageVerified = Time.realtimeSinceStartup-timer;
    124.     }
    125.    
    126.     void TestGetComponentVerified(){
    127.         float timer = Time.realtimeSinceStartup;
    128.        
    129.         for (int i = 0; i < iterations; i++){
    130.             TestReceiver found = other.GetComponent<TestReceiver>();
    131.             if (found != null){
    132.                 found.TestFunction();
    133.             }
    134.         }
    135.        
    136.         lastGetComponentVerified = Time.realtimeSinceStartup-timer;
    137.     }
    138.    
    139.     void TestGetComponentVerifiedViaTag(){
    140.         float timer = Time.realtimeSinceStartup;
    141.        
    142.         for (int i = 0; i < iterations; i++){
    143.             if (other.tag == requiredTag){
    144.                 other.GetComponent<TestReceiver>().TestFunction();
    145.             }
    146.         }
    147.        
    148.         lastGetComponentVerifiedViaTag = Time.realtimeSinceStartup-timer;
    149.     }
    150.    
    151.     void TestGetComponentDict(){
    152.         float timer = Time.realtimeSinceStartup;
    153.        
    154.         for (int i = 0; i < iterations; i++){
    155.             dict[other].TestFunction();
    156.         }
    157.        
    158.         lastGetComponentDict = Time.realtimeSinceStartup-timer;
    159.     }
    160.    
    161.     void TestGetComponentDictVerified(){
    162.         float timer = Time.realtimeSinceStartup;
    163.        
    164.         for (int i = 0; i < iterations; i++){
    165.             if (dict.ContainsKey(other)){
    166.                 dict[other].TestFunction();
    167.             }
    168.         }
    169.        
    170.         lastGetComponentDictVerified = Time.realtimeSinceStartup-timer;
    171.     }
    172.    
    173.     void TestTagCompareString(){
    174.         float timer = Time.realtimeSinceStartup;
    175.        
    176.         for (int i = 0; i < iterations; i++){
    177.             if (other.tag == requiredTag){
    178.                
    179.             }
    180.         }
    181.        
    182.         tagStringComparison = Time.realtimeSinceStartup-timer;
    183.     }
    184.    
    185.     void TestTagCompareTag(){
    186.         float timer = Time.realtimeSinceStartup;
    187.        
    188.         for (int i = 0; i < iterations; i++){
    189.             if (other.CompareTag(requiredTag)){
    190.                
    191.             }
    192.         }
    193.        
    194.         tagCompareTag = Time.realtimeSinceStartup-timer;
    195.     }
    196. }
    197.  
    198.  
    One thing I did note immediately was that the tag comparison changed dramatically. Now it looks like this:

    SendMessage: 1.09ish
    GetComponent: 0.42 ish
    SendMessage Verified: 1.09ish
    GetComponent Verified: 0.47 ish
    GetComponent Verified Via Tag: 1.62ish

    And I added a new test out of curiousity

    Test Tag String Comparison: 1.03 ish
    Test Tag CompareTag(): 0.40 ish

    Which makes me pretty curious as to how CompareTag works under the hood.


    EDIT:

    I added a dictionary and populated it with 101 KVP's to make it actually search a little bit. The result here was:

    GetComponent via Dictionary: 0.31 ish
    GetComponent via Dictionary Verified: 0.60 ish

    Making caching them in a dictionary actually slower than running a GetComponent each time and checking for null. Can anyone see anything wrong with the way I set the cache up?
     
    Last edited: Sep 10, 2011
  7. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    Just to check one last thing while I'm super bored tonight, I made 10 empty scripts called FluffComponentA/B/C/D... and added them to the object to see how GetComponent scales with more components vs how SendMessage scales. This is what I found:

    SendMessage: 1.94
    GetComponent: 0.43

    Looks like the divide increases pretty significantly as you add more and more components to an object and only need to interact with one of them.

    Then I added a test function to each of the 10 new components (so 11 components in all with TestFunction() on the object) and changed the GetComponent portion to get all 11 components and call the function.

    SendMessage: 5.68
    GetComponent: 6.23

    So with a ton of components all needing the message, SendMessage is a slight winner - probably by an even more significant margin if I did a null check. However, the likelihood of that has got to be somewhat slow.

    SendMessage must be doing some sort of caching though, since the difference between 11 components where 1 had the function and 11 components all of which had the function was enormous. I assumed determining if the function existed was the expensive part, not calling it - which suggests that they only make that determination the first time maybe?
     
  8. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    For real speed you just use a static function and call it directly I guess. Most of my game is structured around static functions purely because it avoids a lot of overhead and avoids getcomponent. I use dictionary if things have to be privately addressed, for example with physx.

    If you're like me, you have a solid naming convention so you don't need to worry about compartmentalised code. In my case I'm the sole coder as well :) in team environments, static functions and static variables are bad.
     
  9. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    Just out of curiosity this morning, I decided to try one last thing. I created a simple C# interface and implemented that along all 11 of my components to compare GetComponents(typeof(interface)) with getting each component individually or sending message.

    SendMessage (to 11 components): 5.51
    GetComponent (individually to 11 components): 6.2
    GetComponents (to interface): 3.12

    Note that I called the function with all three methods 2000000 times - which for GetComponents involved casting each component after it was returned. Even with the casting, it was significantly faster than getting the components individually using the generic.

    However, that's obviously not a fair comparison - since the original GetComponent was using the generic. So I switched it over to using the old (typeof()) method:

    GetComponent (individually with typeof and casting): 4.64

    But then, it's still not really fair - since GetComponents would return an empty array if nothing was found and the code would execute error free, where as GetComponent individually isn't doing a null check - so I added a null check to prevent errors:


    So, on an even field (none throwing errors if the components do not exist) I found that...

    SendMessage: 5.5-5.6
    GetComponent: 5.4-5.45
    GetComponents: 3.24-3.27

    So even requiring 11 components, if you use the old (non generic method) GetComponent individually is still faster than SendMessage. If you implement a simple interface and use that to GetComponents it again becomes significantly faster than SendMessage. Doesn't take but two seconds to make something like:

    Code (csharp):
    1.  
    2. public interface IOnSandwich {
    3.     void OnSandwich();
    4. }
    5.  

    Here's the latest test code in case anyone wants to look through / point out anything I did stupid:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public interface ITest {
    7.     void TestFunction();
    8. }
    9.  
    10. public class TestSender : MonoBehaviour {
    11.     public int iterations = 2000000;
    12.    
    13.     public Collider other;
    14.     float lastSendMessage;
    15.     float lastGetComponent;
    16.     float lastSendMessageVerified;
    17.     float lastGetComponentVerified;
    18.     float lastGetComponentVerifiedViaTag;
    19.    
    20.     float lastGetComponentDict;
    21.     float lastGetComponentDictVerified;
    22.    
    23.     float lastGetComponentsInterface;
    24.    
    25.    
    26.     float tagStringComparison;
    27.     float tagCompareTag;
    28.    
    29.     string requiredTag = "Player";
    30.    
    31.     Dictionary<Collider,TestReceiver> dict;
    32.    
    33.     void Awake () {
    34.         dict = new Dictionary<Collider, TestReceiver>();
    35.        
    36.         for (int i = 0; i < 100; i++){
    37.             GameObject go = new GameObject();
    38.             Collider col = go.AddComponent<BoxCollider>();
    39.            
    40.             dict.Add(col, go.AddComponent<TestReceiver>());
    41.         }
    42.        
    43.         dict.Add(other, other.gameObject.AddComponent<TestReceiver>());
    44.     }
    45.    
    46.     // Use this for initialization
    47.     void Start () {
    48.         lastSendMessage = 0;
    49.         lastGetComponent = 0;
    50.     }
    51.    
    52.     // Update is called once per frame
    53.     void Update () {
    54.    
    55.     }
    56.    
    57.     void OnGUI(){
    58.         if (GUILayout.Button("Test SendMessage")){
    59.             TestSendMessage();
    60.         }
    61.         if (GUILayout.Button("Test GetComponent")){
    62.             TestGetComponent();
    63.         }
    64.         if (GUILayout.Button("Test SendMessage Verified")){
    65.             TestSendMessageVerified();
    66.         }
    67.         if (GUILayout.Button("Test GetComponent Verified")){
    68.             TestGetComponentVerified();
    69.         }
    70.         if (GUILayout.Button("Test GetComponent Verified Via Tag")){
    71.             TestGetComponentVerifiedViaTag();
    72.         }
    73.        
    74.         if (GUILayout.Button("Test GetComponent Via Dict")){
    75.             TestGetComponentDict();
    76.         }
    77.        
    78.         if (GUILayout.Button("Test GetComponent Via Dict Verified")){
    79.             TestGetComponentDictVerified();
    80.         }
    81.        
    82.         if (GUILayout.Button("Test GetComponents Interface")){
    83.             TestGetComponentsInterface();
    84.         }
    85.        
    86.         if (GUILayout.Button("Test Tag String Comparison")){
    87.             TestTagCompareString();
    88.         }
    89.         if (GUILayout.Button("Test Tag CompareTag")){
    90.             TestTagCompareTag();
    91.         }
    92.        
    93.         GUILayout.Label("SendMessage: " + lastSendMessage.ToString());
    94.         GUILayout.Label("GetComponent: " + lastGetComponent.ToString());
    95.         GUILayout.Label("SendMessageVerified: " + lastSendMessageVerified.ToString());
    96.         GUILayout.Label("GetComponentVerified: " + lastGetComponentVerified.ToString());
    97.         GUILayout.Label("GetComponentVerifiedViaTag: " + lastGetComponentVerifiedViaTag.ToString());
    98.        
    99.         GUILayout.Label("GetComponentDict: " + lastGetComponentDict.ToString());
    100.         GUILayout.Label("GetComponentDictVerified: " + lastGetComponentDictVerified.ToString());
    101.        
    102.        
    103.         GUILayout.Label("GetComponentsInterface: " + lastGetComponentsInterface.ToString());
    104.        
    105.         GUILayout.Label("TagCompareString: " + tagStringComparison.ToString());
    106.         GUILayout.Label("TagCompareTag: " + tagCompareTag.ToString());
    107.     }
    108.    
    109.     void TestSendMessage(){
    110.         float timer = Time.realtimeSinceStartup;
    111.        
    112.         for (int i = 0; i < iterations; i++){
    113.             other.SendMessage("TestFunction", SendMessageOptions.DontRequireReceiver);
    114.         }
    115.        
    116.         lastSendMessage = Time.realtimeSinceStartup-timer;
    117.     }
    118.    
    119.     void TestGetComponent(){
    120.         float timer = Time.realtimeSinceStartup;
    121.        
    122.         for (int i = 0; i < iterations; i++){
    123.             TestReceiver test = ((TestReceiver)other.GetComponent(typeof(TestReceiver)));
    124.             if (test != null){
    125.                 test.TestFunction();
    126.             }
    127.             FluffComponentA testa = ((FluffComponentA)other.GetComponent(typeof(FluffComponentA)));
    128.             if (testa != null){
    129.                 testa.TestFunction();
    130.             }
    131.             FluffComponentB testb = ((FluffComponentB)other.GetComponent(typeof(FluffComponentB)));
    132.             if (testb != null){
    133.                 testb.TestFunction();
    134.             }
    135.             FluffComponentC testc = ((FluffComponentC)other.GetComponent(typeof(FluffComponentC)));
    136.             if (testc != null){
    137.                 testc.TestFunction();
    138.             }
    139.             FluffComponentD testd = ((FluffComponentD)other.GetComponent(typeof(FluffComponentD)));
    140.             if (testd != null){
    141.                 testd.TestFunction();
    142.             }
    143.             FluffComponentE teste = ((FluffComponentE)other.GetComponent(typeof(FluffComponentE)));
    144.             if (teste != null){
    145.                 teste.TestFunction();
    146.             }
    147.             FluffComponentF testf = ((FluffComponentF)other.GetComponent(typeof(FluffComponentF)));
    148.             if (testf != null){
    149.                 testf.TestFunction();
    150.             }
    151.             FluffComponentG testg = ((FluffComponentG)other.GetComponent(typeof(FluffComponentG)));
    152.             if (testg != null){
    153.                 testg.TestFunction();
    154.             }
    155.             FluffComponentH testh = ((FluffComponentH)other.GetComponent(typeof(FluffComponentH)));
    156.             if (testh != null){
    157.                 testh.TestFunction();
    158.             }
    159.             FluffComponentI testi = ((FluffComponentI)other.GetComponent(typeof(FluffComponentI)));
    160.             if (testi != null){
    161.                 testi.TestFunction();
    162.             }
    163.             FluffComponentJ testj = ((FluffComponentJ)other.GetComponent(typeof(FluffComponentJ)));
    164.             if (testj != null){
    165.                 testj.TestFunction();
    166.             }
    167.            
    168.         }
    169.        
    170.         lastGetComponent = Time.realtimeSinceStartup-timer;
    171.     }
    172.    
    173.     void TestGetComponentsInterface(){
    174.         float timer = Time.realtimeSinceStartup;
    175.        
    176.         for (int i = 0; i < iterations; i++){
    177.             Component[] components = other.GetComponents(typeof(ITest));
    178.            
    179.             for (int j = 0; j < components.Length; j++){
    180.                 ((ITest)components[j]).TestFunction();
    181.             }
    182.         }
    183.        
    184.         lastGetComponentsInterface = Time.realtimeSinceStartup - timer;
    185.     }
    186.    
    187.     void TestSendMessageVerified(){
    188.         float timer = Time.realtimeSinceStartup;
    189.        
    190.         for (int i = 0; i < iterations; i++){
    191.             other.SendMessage("TestFunction", SendMessageOptions.RequireReceiver);
    192.         }
    193.        
    194.         lastSendMessageVerified = Time.realtimeSinceStartup-timer;
    195.     }
    196.    
    197.     void TestGetComponentVerified(){
    198.         float timer = Time.realtimeSinceStartup;
    199.        
    200.         for (int i = 0; i < iterations; i++){
    201.             TestReceiver found = other.GetComponent<TestReceiver>();
    202.             if (found != null){
    203.                 found.TestFunction();
    204.             }
    205.         }
    206.        
    207.         lastGetComponentVerified = Time.realtimeSinceStartup-timer;
    208.     }
    209.    
    210.     void TestGetComponentVerifiedViaTag(){
    211.         float timer = Time.realtimeSinceStartup;
    212.        
    213.         for (int i = 0; i < iterations; i++){
    214.             if (other.tag == requiredTag){
    215.                 other.GetComponent<TestReceiver>().TestFunction();
    216.             }
    217.         }
    218.        
    219.         lastGetComponentVerifiedViaTag = Time.realtimeSinceStartup-timer;
    220.     }
    221.    
    222.     void TestGetComponentDict(){
    223.         float timer = Time.realtimeSinceStartup;
    224.        
    225.         for (int i = 0; i < iterations; i++){
    226.             dict[other].TestFunction();
    227.         }
    228.        
    229.         lastGetComponentDict = Time.realtimeSinceStartup-timer;
    230.     }
    231.    
    232.     void TestGetComponentDictVerified(){
    233.         float timer = Time.realtimeSinceStartup;
    234.        
    235.         for (int i = 0; i < iterations; i++){
    236.             if (dict.ContainsKey(other)){
    237.                 dict[other].TestFunction();
    238.             }
    239.         }
    240.        
    241.         lastGetComponentDictVerified = Time.realtimeSinceStartup-timer;
    242.     }
    243.    
    244.     void TestTagCompareString(){
    245.         float timer = Time.realtimeSinceStartup;
    246.        
    247.         for (int i = 0; i < iterations; i++){
    248.             if (other.tag == requiredTag){
    249.                
    250.             }
    251.         }
    252.        
    253.         tagStringComparison = Time.realtimeSinceStartup-timer;
    254.     }
    255.    
    256.     void TestTagCompareTag(){
    257.         float timer = Time.realtimeSinceStartup;
    258.        
    259.         for (int i = 0; i < iterations; i++){
    260.             if (other.CompareTag(requiredTag)){
    261.                
    262.             }
    263.         }
    264.        
    265.         tagCompareTag = Time.realtimeSinceStartup-timer;
    266.     }
    267. }
    268.  
    269.